java單線程中,若是須要大量的數據庫操做,會在IO方面產生瓶頸,特別是數據庫鏈接失敗時,大量資源會消耗在數據庫鏈接的檢測上,從而使程序的實時響應速度變慢。解決的辦法就是將數據庫操做單獨放置在一個線程中運行,利用隊列的特性實現數據接收和入庫處理,典型的生產者和消費者的例子。這樣爲模塊化及進一步改進程序提供方便。 線程的實現只要extends Thread就好了,線程的工做在run()方法中實現。實現線程自啓動,最好在構造函數中加一句start(),這個很容易。 集合若是選用blockingqueue,要本身實現一堆方法,挺麻煩的,若是使用java.util.Vector就方便不少,相對於ArrayList來講,它線程是安全的。 最近項目須要,寫了一個例子,爲告終構清晰,去掉了冗餘的各類處理,適合有相似的需求的朋友在此基礎上加入本身特有的需求實現。 主要代碼以下: import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Calendar; import java.util.Vector; import com.StartPoint; import com.AInfo; //引用自定義數據類型 import com.CInfo; //引用自定義數據類型 import com.GInfo; //引用自定義數據類型 public class OperateDB extends Thread { Connection con; private Vector<GInfo> QueueGPS; private Vector<CInfo> QueueCCS; private Vector<AInfo> QueueCGZ; private int intListCount=0; public OperateDB(Connection pcon) { con=pcon; QueueGPS = new Vector<GInfo>(); QueueCCS = new Vector<CInfo>(); QueueCGZ = new Vector<AInfo>(); start(); } public int insertGps(GInfo oItem) { QueueGPS.add(oItem); return ++intListCount; } public void run() { while (true) { try { if (intListCount > 0) { int len = QueueGPS.size(); for (int i = 0; i < len; i++) { inputGInfo(QueueGPS.remove(0)); intListCount--; } len = QueueCCS.size(); for (int i = 0; i < len; i++) { inputCInfo(QueueCCS.remove(0)); intListCount--; } len = QueueCGZ.size(); for (int i = 0; i < len; i++) { inputAInfo(QueueCGZ.remove(0)); intListCount--; } } else { Thread.sleep(2000); } } catch (Exception e) { e.printStackTrace(); } } } /** * 增長一條記錄 */ private int inputGInfo(GInfo o) { int tmp = 0; try { String sql = "insert into t_ginfo(car,intime,gtime,mainid,subid) values(?,sysdate,to_date(?,'yyyy-mm-dd hh24:mi:ss'),?,?)"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, o.getCAR()); pstmt.setString(2, o.gTime()); pstmt.setInt(3, o.getMainId()); pstmt.setInt(4, o.getSubId()); tmp = pstmt.executeUpdate(); pstmt.close(); } catch (Exception e) { e.printStackTrace(); } return tmp; } private int inputCInfo(CInfo o) { int tmp = 0; try { String sql = "insert into t_cinfo(car,intime,gtime,mainid,subid) values(?,sysdate,to_date(?,'yyyy-mm-dd hh24:mi:ss'),?,?)"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, o.getCAR()); pstmt.setString(2, o.gTime()); pstmt.setInt(3, o.getMainId()); pstmt.setInt(4, o.getSubId()); tmp = pstmt.executeUpdate(); pstmt.close(); } catch (Exception e) { e.printStackTrace(); } return tmp; } private int inputAInfo(AInfo o) { int tmp = 0; try { String sql = "insert into t_ainfo(car,intime,gtime,mainid,subid) values(?,sysdate,to_date(?,'yyyy-mm-dd hh24:mi:ss'),?,?)"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, o.getCAR()); pstmt.setString(2, o.gTime()); pstmt.setInt(3, o.getMainId()); pstmt.setInt(4, o.getSubId()); tmp = pstmt.executeUpdate(); pstmt.close(); System.out.println("------告警數據插入成功"); } catch (Exception e) { e.printStackTrace(); } return tmp; } } 調用以下: OperateDB db = new OperateDB(getConnection()); public void run() { while(true) { String sData = GetReceiveString(); GInfo g = GetGInfoByString(sData); db.insertGInfo(g); } }