Java多線程ThreadLocal

關於ThreadLocal,java中有一個很相似的對比機制:clone.

他們的思想都是,給當前的線程/方法一個本地變量的copy,各個線程/方法雖然看起來是共享了一個變量,但相互之間並不干擾交互。

ThreadLocal是非常輕量級的保證線程安全的機制,不涉及鎖,不涉及同步阻塞。完全是線程內部的一個變量。

那有的同學可能會問,既然這樣幹嘛還要設計成類的成員變量,直接在方法裏面聲明然後在方法之間傳遞不就好了。這樣其實完全可以,但是相對來說代碼結構會更加複雜,不利於後期的維護,我們來看一個ThreadLocal的例子:


  1. public class ConnectionManager {  
  2.   
  3.     /** 線程內共享Connection,ThreadLocal通常是全局的,支持泛型 */  
  4.     private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();  
  5.       
  6.     public static Connection getCurrConnection() {  
  7.         // 獲取當前線程內共享的Connection  
  8.         Connection conn = threadLocal.get();  
  9.         try {  
  10.             // 判斷連接是否可用  
  11.             if(conn == null || conn.isClosed()) {  
  12.                 // code : 創建新的Connection賦值給conn  
  13.                 // code : 保存Connection  
  14.                 threadLocal.set(conn);  
  15.             }  
  16.         } catch (SQLException e) {  
  17.         }  
  18.         return conn;  
  19.     }  
  20.       
  21.     /** 
  22.      * 關閉當前數據庫連接 
  23.      */  
  24.     public static void close() {  
  25.         // 獲取當前線程內共享的Connection  
  26.         Connection conn = threadLocal.get();  
  27.         try {  
  28.             // 判斷是否已經關閉  
  29.             if(conn != null && !conn.isClosed()) {  
  30.                 // 關閉資源  
  31.                 conn.close();  
  32.                 // 移除Connection  
  33.                 threadLocal.remove();  
  34.                 conn = null;  
  35.             }  
  36.         } catch (SQLException e) {  
  37.             // 異常處理  
  38.         }  
  39.     }  
  40. }  

這是ThreadLocal應用的一個典型場景,大家可以琢磨一下兩個問題:

1.如果不用ThreadLocal會怎麼樣?

2.如果不用ThreadLocal該怎麼做?


如果最後你覺得在這種場景下ThreadLocal是最好的選擇那麼你基本就理解了ThreadLocal和它的使用場景。


接下來看一下Threadlocal的內部實現原理。

如果看過Thread和ThreadLocal源碼的同學會發現,在Thread類內部有一個ThreadLocal.ThreadLocalMap這樣的一個成員變量。在調用ThreadLocal的set/get時,程序會根據當前線程來獲取對應的ThreadLocalMap,即Thread對象的ThreadLocal.ThreadLocalMap這個表,然後把值放入該Map中,即這個值是在線程內部而非ThreadLocal內部。這樣在一個Thread對象裏可以存放多個TheadLocal對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章