java jdbc娣卞叆鐞嗚В锛坈onnection涓巘hreadlocal涓庢暟鎹簱杩炴帴姹犲拰浜嬪姟瀹烇級

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java jdbc娣卞叆鐞嗚В锛坈onnection涓巘hreadlocal涓庢暟鎹簱杩炴帴姹犲拰浜嬪姟瀹烇級相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/i_1__1_' title='i++'>i++   ==   session   tac   throws   keep   涓婁笅   timeout   name   

1.jdbc杩炴帴鏁版嵁搴擄紝灏辫繖鏍峰瓙

Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection conn = DriverManager.getConnection(jdbcUrl);

2.閫氳繃浼犲叆jdbc url鐢―rivermanager.getConnection(jdbcurl)杩炴帴鏁版嵁搴擄紝

娉ㄦ剰锛氫竴娆rivermanager.getConnection(jdbcurl)鑾峰緱鍙槸涓€涓猚onnection锛屽苟涓嶈兘婊¤冻楂樺苟鍙戞儏鍐点€傚洜涓篶onnection涓嶆槸绾跨▼瀹夊叏鐨勶紝涓€涓猚onnection瀵瑰簲鐨勬槸涓€涓簨鐗┿€?/p>

3.鎵€浠ユ暟鎹簱杩炴帴姹狅紝鏄娆rivermanager.getConnection(jdbcurl)锛岃幏鍙栧涓猚onnection鏀惧叆hashmap涓€?/p>

4.姣忔鑾峰緱connection閮介渶瑕佹氮璐筩pu璧勬簮鍜屽唴瀛樿祫婧愶紝鏄緢娴垂璧勬簮鐨勩€傛墍浠ヨ癁鐢熶簡鏁版嵁搴撹繛鎺ユ睜銆?/p>

5.鏁版嵁搴撹繛鎺ユ睜閮ㄥ垎婧愮爜锛?/p>

娉ㄦ剰pool.getConnection()锛岄兘鏄厛浠巘hreadlocal閲岄潰鎷跨殑锛屽鏋渢hreadlocal閲岄潰鏈夛紝鍒欑敤锛屼繚璇佺嚎绋嬮噷鐨勫涓猟ao鎿嶄綔锛岀敤鐨勬槸鍚屼竴涓猚onnection锛屼互淇濊瘉浜嬪姟銆?/p>

濡傛灉鏂扮嚎绋嬶紝鍒欏皢鏂扮殑connection鏀惧湪threadlocal閲岋紝鍐峠et缁欏埌绾跨▼銆?/p>

鐫€閲嶇湅浠ヤ笅鍑犱釜鏂规硶锛岃鏄庢暟鎹簱杩炴帴姹狅紝鏄皢connection鏀捐繘threadlocal閲岀殑锛屼互淇濊瘉姣忎釜绾跨▼浠庤繛鎺ユ睜涓幏寰楃殑閮芥槸绾跨▼鑷繁鐨刢onnection銆?/p>

 

  1.  // 灏嗙嚎绋嬪拰杩炴帴缁戝畾锛屼繚璇佷簨鍔¤兘缁熶竴鎵ц  
  2.  鎴愬憳鍙橀噺   private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); 
 // 鑾峰緱褰撳墠杩炴帴  
    public Connection getCurrentConnecton(){  
        // 榛樿绾跨▼閲岄潰鍙? 
        Connection conn = threadLocal.get();  
        if(!isValid(conn)){  
            conn = getConnection();  
        }  
        return conn;  
    }  

// 鑾峰緱杩炴帴  
    public synchronized Connection getConnection() {  
        Connection conn = null;  
        try {  
            // 鍒ゆ柇鏄惁瓒呰繃鏈€澶ц繛鎺ユ暟闄愬埗  
            if(contActive < this.dbBean.getMaxActiveConnections()){  
                if (freeConnection.size() > 0) {  
                    conn = freeConnection.get(0);  
                    if (conn != null) {  
                        threadLocal.set(conn);  
                    }  
                    freeConnection.remove(0);  
                } else {  
                    conn = newConnection();  
                }  
                  
            }else{  
                // 缁х画鑾峰緱杩炴帴,鐩村埌浠庢柊鑾峰緱杩炴帴  
                wait(this.dbBean.getConnTimeOut());  
                conn = getConnection();  
            }  
            if (isValid(conn)) {  
                activeConnection.add(conn);  
                contActive ++;  
            }  
        } catch (SQLException e) {  
            e.printStackTrace();  
        } catch (ClassNotFoundException e) {  
            e.printStackTrace();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        return conn;  
    }
public synchronized void releaseConn(Connection conn) throws SQLException {  
        if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) {  
            freeConnection.add(conn);  
            activeConnection.remove(conn);  
            contActive --;  
            threadLocal.remove();  
            // 鍞ら啋鎵€鏈夋寰呯瓑寰呯殑绾跨▼锛屽幓鎶㈣繛鎺? 
            notifyAll();  
        }  
    } 
鐒跺悗鍐嶇潃閲嶇悊瑙f娈佃瘽
鎶€鏈浘鐗? src=
棣栧厛,LZ鏄蹇典笂鐨勯敊璇?浠€涔堟槸绾跨▼姹?浠€涔堟槸ThreadLocal???
   绾跨▼姹?涓洪伩鍏嶄笉蹇呰鐨勫垱寤?閿€姣乧onnection鑰屽瓨鍦ㄧ殑,鍏朵腑鍖呮嫭娲诲姩,绛夊緟,鏈€灏忕瓑灞炴€?cop3,proxy杩炴帴姹犻兘鍙互閰嶇疆杩欎簺鐜╂剰;
   
   鑷充簬涓轰粈涔堣鐢═hreadLocal鍛?杩欎釜鍜岃繛鎺ユ睜鏃犲叧,鎴戣涓烘洿澶氱殑鏄拰绋嬪簭鏈韩鐩稿叧,涓轰簡鏇存竻妤氱殑璇存槑,鎴戜妇涓緥瀛?   servlet涓幏鍙栦竴涓繛鎺?棣栧厛,servlet鏄嚎绋嬪畨鍏ㄧ殑鍚?
     class MyServlet extends HttpServlet{
         private Connection conn;
     }
     ok,閬楁喚鐨勫憡璇変綘,杩欎釜conn骞朵笉鏄畨鍏ㄧ殑,鎵€鏈夎姹傝繖涓猻ervlet鐨勮繛鎺?浣跨敤鐨勯兘鏄竴涓狢onnection,杩欎釜灏辨槸鑷村懡鐨勪簡.澶氫釜浜轰娇鐢ㄥ悓涓€涓繛鎺?绠椾笂寤惰繜鍟ョ殑,澶╃煡閬撴暟鎹細鎴愪粈涔堟牱.
     鍥犳鎴戜滑瑕佷繚璇丆onnection瀵规瘡涓姹傞兘鏄敮涓€鐨?杩欎釜鏃跺€欏氨鍙互鐢ㄥ埌ThreadLocal浜?淇濊瘉姣忎釜绾跨▼閮芥湁鑷繁鐨勮繛鎺?
     鏀逛负 private ThreadLocal<Connection> ct = new ThreadLocal<Connnection>();
     鐒跺悗浠庤繛鎺ユ睜鑾峰彇Connection,set鍒癱t涓?鍐峠et灏辫浜?鑷充簬寰楀埌鐨勬槸鍝釜Connection灏辨槸杩炴帴姹犵殑闂浜?浣犱篃绠′笉鍒?
鎶€鏈浘鐗? src=

 

Hibernate鐨勬暟鎹簱杩炴帴姹犲氨鏄皢connection鏀捐繘threadlocal瀹炵幇鐨勶紒锛侊紒
Hibernate鐨勬暟鎹簱杩炴帴姹犲氨鏄皢connection鏀捐繘threadlocal瀹炵幇鐨勶紒锛侊紒
Hibernate鐨勬暟鎹簱杩炴帴姹犲氨鏄皢connection鏀捐繘threadlocal瀹炵幇鐨勶紒锛侊紒


鎶€鏈浘鐗? src=
public class ConnectionPool implements IConnectionPool {  
    // 杩炴帴姹犻厤缃睘鎬? 
    private DBbean dbBean;  
    private boolean isActive = false; // 杩炴帴姹犳椿鍔ㄧ姸鎬? 
    private int contActive = 0;// 璁板綍鍒涘缓鐨勬€荤殑杩炴帴鏁? 
      
    // 绌洪棽杩炴帴  
    private List<Connection> freeConnection = new Vector<Connection>();  
    // 娲诲姩杩炴帴  
    private List<Connection> activeConnection = new Vector<Connection>();  
  
  1.  // 灏嗙嚎绋嬪拰杩炴帴缁戝畾锛屼繚璇佷簨鍔¤兘缁熶竴鎵ц
  2.     private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); 

public ConnectionPool(DBbean dbBean) { super(); this.dbBean = dbBean; init(); cheackPool(); } // 鍒濆鍖? public void init() { try { Class.forName(dbBean.getDriverName()); for (int i = 0; i < dbBean.getInitConnections(); i++) { Connection conn; conn = newConnection(); // 鍒濆鍖栨渶灏忚繛鎺ユ暟 if (conn != null) { freeConnection.add(conn); contActive++; } } isActive = true; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } // 鑾峰緱褰撳墠杩炴帴 public Connection getCurrentConnecton(){ // 榛樿绾跨▼閲岄潰鍙? Connection conn = threadLocal.get(); if(!isValid(conn)){ conn = getConnection(); } return conn; } // 鑾峰緱杩炴帴 public synchronized Connection getConnection() { Connection conn = null; try { // 鍒ゆ柇鏄惁瓒呰繃鏈€澶ц繛鎺ユ暟闄愬埗 if(contActive < this.dbBean.getMaxActiveConnections()){ if (freeConnection.size() > 0) { conn = freeConnection.get(0); if (conn != null) { threadLocal.set(conn); } freeConnection.remove(0); } else { conn = newConnection(); } }else{ // 缁х画鑾峰緱杩炴帴,鐩村埌浠庢柊鑾峰緱杩炴帴 wait(this.dbBean.getConnTimeOut()); conn = getConnection(); } if (isValid(conn)) { activeConnection.add(conn); contActive ++; } } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return conn; } // 鑾峰緱鏂拌繛鎺? private synchronized Connection newConnection() throws ClassNotFoundException, SQLException { Connection conn = null; if (dbBean != null) { Class.forName(dbBean.getDriverName()); conn = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword()); } return conn; } // 閲婃斁杩炴帴 public synchronized void releaseConn(Connection conn) throws SQLException { if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) { freeConnection.add(conn); activeConnection.remove(conn); contActive --; threadLocal.remove(); // 鍞ら啋鎵€鏈夋寰呯瓑寰呯殑绾跨▼锛屽幓鎶㈣繛鎺? notifyAll(); } } // 鍒ゆ柇杩炴帴鏄惁鍙敤 private boolean isValid(Connection conn) { try { if (conn == null || conn.isClosed()) { return false; } } catch (SQLException e) { e.printStackTrace(); } return true; } // 閿€姣佽繛鎺ユ睜 public synchronized void destroy() { for (Connection conn : freeConnection) { try { if (isValid(conn)) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } for (Connection conn : activeConnection) { try { if (isValid(conn)) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } isActive = false; contActive = 0; } // 杩炴帴姹犵姸鎬? @Override public boolean isActive() { return isActive; } // 瀹氭椂妫€鏌ヨ繛鎺ユ睜鎯呭喌 @Override public void cheackPool() { if(dbBean.isCheakPool()){ new Timer().schedule(new TimerTask() { @Override public void run() { // 1.瀵圭嚎绋嬮噷闈㈢殑杩炴帴鐘舵€? // 2.杩炴帴姹犳渶灏?鏈€澶ц繛鎺ユ暟 // 3.鍏朵粬鐘舵€佽繘琛屾鏌ワ紝鍥犱负杩欓噷杩橀渶瑕佸啓鍑犱釜绾跨▼绠$悊鐨勭被锛屾殏鏃跺氨涓嶆坊鍔犱簡 System.out.println("绌虹嚎姹犺繛鎺ユ暟锛?+freeConnection.size()); System.out.println("娲诲姩杩炴帴鏁帮細锛?+activeConnection.size()); System.out.println("鎬荤殑杩炴帴鏁帮細"+contActive); } },dbBean.getLazyCheck(),dbBean.getPeriodCheck()); } } }
鎶€鏈浘鐗? src=

 

Why ThreadLocal?

鏃犺濡備綍锛岃缂栧啓涓€涓绾跨▼瀹夊叏(Thread-safe)鐨勭▼搴忔槸鍥伴毦鐨勶紝涓轰簡璁╃嚎绋嬪叡浜祫婧愶紝蹇呴』灏忓績鍦板鍏变韩璧勬簮杩涜鍚屾锛屽悓姝ュ甫鏉ヤ竴瀹氱殑鏁堣兘寤惰繜锛岃€屽彟涓€鏂归潰锛屽湪澶勭悊鍚屾鐨勬椂鍊欙紝鍙堣娉ㄦ剰瀵硅薄鐨勯攣瀹氫笌閲婃斁锛岄伩鍏嶄骇鐢熸缁擄紝绉嶇鍥犵礌閮戒娇寰楃紪鍐欏绾跨▼绋嬪簭鍙樺緱鍥伴毦銆?/p>

灏濊瘯浠庡彟涓€涓搴︽潵鎬濊€冨绾跨▼鍏变韩璧勬簮鐨勯棶棰橈紝鏃㈢劧鍏变韩璧勬簮杩欎箞鍥伴毦锛岄偅涔堝氨骞茶剢涓嶈鍏变韩锛屼綍涓嶄负姣忎釜绾跨▼鍒涢€犱竴涓祫婧愮殑澶嶆湰銆傚皢姣忎竴涓嚎绋嬪瓨鍙栨暟鎹殑琛屼负鍔犱互闅旂锛屽疄鐜扮殑鏂规硶灏辨槸缁欎簣姣忎釜绾跨▼涓€涓壒瀹氱┖闂存潵淇濈璇ョ嚎绋嬫墍鐙韩鐨勮祫婧?/p>

 

浠€涔堟槸ThreadLocal锛?/strong>

椤惧悕鎬濅箟瀹冩槸local variable锛堢嚎绋嬪眬閮ㄥ彉閲忥級銆傚畠鐨勫姛鐢ㄩ潪甯哥畝鍗曪紝灏辨槸涓烘瘡涓€涓娇鐢ㄨ鍙橀噺鐨勭嚎绋嬮兘鎻愪緵涓€涓彉閲忓€肩殑鍓湰锛屾槸姣忎竴涓嚎绋嬮兘鍙互鐙珛鍦版敼鍙樿嚜宸辩殑鍓湰锛岃€屼笉浼氬拰鍏跺畠绾跨▼鐨勫壇鏈啿绐併€備粠绾跨▼鐨勮搴︾湅锛屽氨濂藉儚姣忎竴涓嚎绋嬮兘瀹屽叏鎷ユ湁璇ュ彉閲忋€?/p>

浣跨敤鍦烘櫙

  1. To keep state with a thread (user-id, transaction-id, logging-id)
  2. To cache objects which you need frequently

ThreadLocal绫?nbsp; 瀹炵幇绾跨▼鑼冨洿鐨勫叡浜彉閲?/strong>

瀹冧富瑕佺敱鍥涗釜鏂规硶缁勬垚initialValue()锛実et()锛宻et(T)锛宺emove()锛屽叾涓€煎緱娉ㄦ剰鐨勬槸initialValue()锛岃鏂规硶鏄竴涓猵rotected鐨勬柟娉曪紝鏄剧劧鏄负浜嗗瓙绫婚噸鍐欒€岀壒鎰忓疄鐜扮殑銆傝鏂规硶杩斿洖褰撳墠绾跨▼鍦ㄨ绾跨▼灞€閮ㄥ彉閲忕殑鍒濆鍊硷紝杩欎釜鏂规硶鏄竴涓欢杩熻皟鐢ㄦ柟娉曪紝鍦ㄤ竴涓嚎绋嬬1娆¤皟鐢╣et()鎴栬€卻et(Object)鏃舵墠鎵ц锛屽苟涓斾粎鎵ц1娆°€俆hreadLocal涓殑纭疄瀹炵幇鐩存帴杩斿洖涓€涓猲ull锛?/p>

 

ThreadLocal鐨勫師鐞?/p>

ThreadLocal鏄浣曞仛鍒颁负姣忎竴涓嚎绋嬬淮鎶ゅ彉閲忕殑鍓湰鐨勫憿锛熷叾瀹炲疄鐜扮殑鎬濊矾寰堢畝鍗曪紝鍦═hreadLocal绫讳腑鏈変竴涓狹ap锛岀敤浜庡瓨鍌ㄦ瘡涓€涓嚎绋嬬殑鍙橀噺鐨勫壇鏈€傛瘮濡備笅闈㈢殑绀轰緥瀹炵幇锛?/p>

public class ThreadLocal
{
銆€ private Map values = Collections.synchronizedMap(new HashMap());
銆€ public Object get()
銆€ {
銆€銆€  Thread curThread = Thread.currentThread();
銆€銆€  Object o = values.get(curThread);
銆€銆€  if (o == null && !values.containsKey(curThread))
銆€銆€  {
銆€銆€  銆€  o = initialValue();
銆€銆€  銆€  values.put(curThread, o);
銆€銆€  }
銆€銆€  return o;
銆€}

銆€public void set(Object newValue)
銆€{
銆€銆€  values.put(Thread.currentThread(), newValue);
銆€}

銆€public Object initialValue()
銆€{
銆€銆€  return null;
銆€}
}

ThreadLocal 鐨勪娇鐢?/strong>

浣跨敤鏂规硶涓€锛?/p>

hibernate鐨勬枃妗f椂鐪嬪埌浜嗗叧浜庝娇ThreadLocal绠$悊澶氱嚎绋嬭闂殑閮ㄥ垎銆傚叿浣撲唬鐮佸涓?br />
1.  public static final ThreadLocal session = new ThreadLocal();
2.  public static Session currentSession() {
3.      Session s = (Session)session.get();
4.      //open a new session,if this session has none
5.   if(s == null){
6.      s = sessionFactory.openSession();
7.      session.set(s);
8.   }
      return s;
9. }

鎴戜滑閫愯鍒嗘瀽
1銆?鍒濆鍖栦竴涓猅hreadLocal瀵硅薄锛孴hreadLocal鏈変笁涓垚鍛樻柟娉?get()銆乻et()銆乮nitialvalue()銆?br />    濡傛灉涓嶅垵濮嬪寲initialvalue锛屽垯initialvalue杩斿洖null銆?br />3銆?session鐨刧et鏍规嵁褰撳墠绾跨▼杩斿洖鍏跺搴旂殑绾跨▼鍐呴儴鍙橀噺锛屼篃灏辨槸鎴戜滑闇€瑕佺殑net.sf.hibernate.Session锛堢浉褰撲簬瀵瑰簲姣忎釜鏁版嵁搴?/a>杩炴帴锛?澶氱嚎绋嬫儏鍐典笅鍏变韩鏁版嵁搴撻摼鎺ユ槸涓嶅畨鍏ㄧ殑銆俆hreadLocal淇濊瘉浜嗘瘡涓嚎绋嬮兘鏈夎嚜宸辩殑s锛堟暟鎹簱杩炴帴锛夈€?br />5銆傚鏋滄槸璇ョ嚎绋嬪垵娆¤闂紝鑷劧锛宻锛堟暟鎹簱杩炴帴锛変細鏄痭ull锛屾帴鐫€鍒涘缓涓€涓猄ession锛屽叿浣撳氨鏄6銆?br />6銆傚垱寤轰竴涓暟鎹簱杩炴帴瀹炰緥 s
7銆備繚瀛樿鏁版嵁搴撹繛鎺鍒癟hreadLocal涓€?br />8銆傚鏋滃綋鍓嶇嚎绋嬪凡缁忚闂繃鏁版嵁搴撲簡锛屽垯浠巗ession涓璯et()灏卞彲浠ヨ幏鍙栬绾跨▼涓婃鑾峰彇杩囩殑杩炴帴瀹炰緥銆?/p>

浣跨敤鏂规硶浜?/p>

褰撹缁欑嚎绋嬪垵濮嬪寲涓€涓壒娈婂€兼椂锛岄渶瑕佽嚜宸卞疄鐜癟hreadLocal鐨勫瓙绫诲苟閲嶅啓璇ユ柟娉曪紝閫氬父浣跨敤涓€涓唴閮ㄥ尶鍚嶇被瀵筎hreadLocal杩涜瀛愮被鍖栵紝EasyDBO涓垱寤簀dbc杩炴帴涓婁笅鏂囧氨鏄繖鏍峰仛鐨勶細

 public class JDBCContext{
 private static Logger logger = Logger.getLogger(JDBCContext.class);
 private DataSource ds;
 protected Connection connection;
 private boolean isValid = true;
 private static ThreadLocal jdbcContext;
 
 private JDBCContext(DataSource ds){
  this.ds = ds;
  createConnection();  
 }
 public static JDBCContext getJdbcContext(javax.sql.DataSource ds)
 {  
  if(jdbcContext==null)jdbcContext=new JDBCContextThreadLocal(ds);
  JDBCContext context = (JDBCContext) jdbcContext.get();
  if (context == null) {
   context = new JDBCContext(ds);
  }
  return context;
 }

 private static class JDBCContextThreadLocal extends ThreadLocal {
  public javax.sql.DataSource ds;
  public JDBCContextThreadLocal(javax.sql.DataSource ds)
  {
   this.ds=ds;
  }
  protected synchronized Object initialValue() {
   return new JDBCContext(ds);
  }
 }
}

浣跨敤鍗曚緥妯″紡锛屼笉鍚岀殑绾跨▼璋冪敤getJdbcContext()鑾峰緱鑷繁鐨刯dbcContext锛岄兘鏄€氳繃JDBCContextThreadLocal 鍐呯疆瀛愮被鏉ヨ幏寰桱DBCContext瀵硅薄鐨勭嚎绋嬪眬閮ㄥ彉閲?/p>

鏈枃閮ㄥ垎杞嚜http://blog.csdn.net/wenzhihui_2010/article/details/8985575

以上是关于java jdbc娣卞叆鐞嗚В锛坈onnection涓巘hreadlocal涓庢暟鎹簱杩炴帴姹犲拰浜嬪姟瀹烇級的主要内容,如果未能解决你的问题,请参考以下文章

viewport銆佸竷灞€瑙嗗彛銆佽瑙夎鍙c€佺悊鎯宠鍙?娣卞叆鐞嗚В

娣卞叆婧愮爜鍒嗘瀽锛岀紦瀛樹箣鐜?Caffeine 涓轰綍杩欎箞鐚?

娣卞叆瀛︿範 Redis绯诲垪

L2-3 娣卞叆铏庣┐ (25鍒?

娣卞叆娴呭嚭JavaScript杩愯鏈哄埗

HTTP keepalive璇﹁В