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 name1.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>
- // 灏嗙嚎绋嬪拰杩炴帴缁戝畾锛屼繚璇佷簨鍔¤兘缁熶竴鎵ц
- 鎴愬憳鍙橀噺 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娈佃瘽
棣栧厛,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灏辨槸杩炴帴姹犵殑闂浜?浣犱篃绠′笉鍒?
Hibernate鐨勬暟鎹簱杩炴帴姹犲氨鏄皢connection鏀捐繘threadlocal瀹炵幇鐨勶紒锛侊紒
Hibernate鐨勬暟鎹簱杩炴帴姹犲氨鏄皢connection鏀捐繘threadlocal瀹炵幇鐨勶紒锛侊紒
Hibernate鐨勬暟鎹簱杩炴帴姹犲氨鏄皢connection鏀捐繘threadlocal瀹炵幇鐨勶紒锛侊紒
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>();
- // 灏嗙嚎绋嬪拰杩炴帴缁戝畾锛屼繚璇佷簨鍔¤兘缁熶竴鎵ц
- 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()); } } }
Why ThreadLocal?
鏃犺濡備綍锛岃缂栧啓涓€涓绾跨▼瀹夊叏(Thread-safe)鐨勭▼搴忔槸鍥伴毦鐨勶紝涓轰簡璁╃嚎绋嬪叡浜祫婧愶紝蹇呴』灏忓績鍦板鍏变韩璧勬簮杩涜鍚屾锛屽悓姝ュ甫鏉ヤ竴瀹氱殑鏁堣兘寤惰繜锛岃€屽彟涓€鏂归潰锛屽湪澶勭悊鍚屾鐨勬椂鍊欙紝鍙堣娉ㄦ剰瀵硅薄鐨勯攣瀹氫笌閲婃斁锛岄伩鍏嶄骇鐢熸缁擄紝绉嶇鍥犵礌閮戒娇寰楃紪鍐欏绾跨▼绋嬪簭鍙樺緱鍥伴毦銆?/p>
灏濊瘯浠庡彟涓€涓搴︽潵鎬濊€冨绾跨▼鍏变韩璧勬簮鐨勯棶棰橈紝鏃㈢劧鍏变韩璧勬簮杩欎箞鍥伴毦锛岄偅涔堝氨骞茶剢涓嶈鍏变韩锛屼綍涓嶄负姣忎釜绾跨▼鍒涢€犱竴涓祫婧愮殑澶嶆湰銆傚皢姣忎竴涓嚎绋嬪瓨鍙栨暟鎹殑琛屼负鍔犱互闅旂锛屽疄鐜扮殑鏂规硶灏辨槸缁欎簣姣忎釜绾跨▼涓€涓壒瀹氱┖闂存潵淇濈璇ョ嚎绋嬫墍鐙韩鐨勮祫婧?/p>
浠€涔堟槸ThreadLocal锛?/strong>
椤惧悕鎬濅箟瀹冩槸local variable锛堢嚎绋嬪眬閮ㄥ彉閲忥級銆傚畠鐨勫姛鐢ㄩ潪甯哥畝鍗曪紝灏辨槸涓烘瘡涓€涓娇鐢ㄨ鍙橀噺鐨勭嚎绋嬮兘鎻愪緵涓€涓彉閲忓€肩殑鍓湰锛屾槸姣忎竴涓嚎绋嬮兘鍙互鐙珛鍦版敼鍙樿嚜宸辩殑鍓湰锛岃€屼笉浼氬拰鍏跺畠绾跨▼鐨勫壇鏈啿绐併€備粠绾跨▼鐨勮搴︾湅锛屽氨濂藉儚姣忎竴涓嚎绋嬮兘瀹屽叏鎷ユ湁璇ュ彉閲忋€?/p>
浣跨敤鍦烘櫙
- To keep state with a thread (user-id, transaction-id, logging-id)
- 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 /> 浣跨敤鏂规硶浜?/p>
褰撹缁欑嚎绋嬪垵濮嬪寲涓€涓壒娈婂€兼椂锛岄渶瑕佽嚜宸卞疄鐜癟hreadLocal鐨勫瓙绫诲苟閲嶅啓璇ユ柟娉曪紝閫氬父浣跨敤涓€涓唴閮ㄥ尶鍚嶇被瀵筎hreadLocal杩涜瀛愮被鍖栵紝EasyDBO涓垱寤簀dbc杩炴帴涓婁笅鏂囧氨鏄繖鏍峰仛鐨勶細 public class JDBCContext{ private static class JDBCContextThreadLocal extends ThreadLocal { 浣跨敤鍗曚緥妯″紡锛屼笉鍚岀殑绾跨▼璋冪敤getJdbcContext()鑾峰緱鑷繁鐨刯dbcContext锛岄兘鏄€氳繃JDBCContextThreadLocal 鍐呯疆瀛愮被鏉ヨ幏寰桱DBCContext瀵硅薄鐨勭嚎绋嬪眬閮ㄥ彉閲?/p>
鏈枃閮ㄥ垎杞嚜http://blog.csdn.net/wenzhihui_2010/article/details/8985575
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>
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;
}
public javax.sql.DataSource ds;
public JDBCContextThreadLocal(javax.sql.DataSource ds)
{
this.ds=ds;
}
protected synchronized Object initialValue() {
return new JDBCContext(ds);
}
}
}
以上是关于java jdbc娣卞叆鐞嗚В锛坈onnection涓巘hreadlocal涓庢暟鎹簱杩炴帴姹犲拰浜嬪姟瀹烇級的主要内容,如果未能解决你的问题,请参考以下文章
viewport銆佸竷灞€瑙嗗彛銆佽瑙夎鍙c€佺悊鎯宠鍙?娣卞叆鐞嗚В