java中threadlocal的理解


java中threadlocal的理解


一、threadlocal的生命周期和ThreadLocalMap的生命周期

可以吧TreadLocal看做是一個map來使用,只不過這個map是指向當前線程中的threadLocals(ThreadLocalMap.class),這個threadLocals采用懶漢單例在一個線程中是唯一的。

Thread中的threadLocals屬性,存放的是當前線程在不同TreadLocal實例中的值ThreadLocalMap<TreadLocal,T>

 

1 public void set(T value) {
2      Thread t = Thread.currentThread();
3      ThreadLocalMap map = getMap(t);//return t.threadLocals;這里表示只有一個ThreadLocalMap副本
4      if (map != null)//采用懶漢模式
5          map.set(this, value);
6      else
7          createMap(t, value);//t.threadLocals = new ThreadLocalMap(this, firstValue);
8  }

 

可以通過查看當前線程中的threadLocals變量,來看當前線程持有多少個threadLocal,以及存的值。

ThreadLocalMap實例的生命周期隨着線程的結束而結束,因為ThreadLocalMap實例的唯一引用只存在當前線程中。ThreadLocal的生命周期,需要gc來決定,因為他的引用可能存在於多個線程中,此引用為弱引用。

弱引用的存在,導致可能內存泄露。當threadlocal=null,沒有任何強引用實例指向threadLocals中的key本來指向的threadlocal實例,gc回收threadlocal,導致val永遠不會被釋放。采用以下代碼來取代=null的操作,用remove函數來清除,threadLocals。

1 ThreadLocal local1 = new ThreadLocal();
2 local.remove();

 

 

 


二、ThreadLocal的作用

對於那些需要數據隔離,可以用ThreadLocal。

對於一個線程中的一個ThreadLocal只能存一個T類型的數據。(T為泛型)

ThreadLocal是線程安全的,所以可以用來封裝線程不安全的實例,不同線程之間新創建實例,保證線程安全。(另一種模式就是單例模式。)


三、示例

比較經典的例子就是github中的PageHelper中保存Page信息的時候使用了ThreadLocal。考慮到數據的同步,已經一個線程只會順序執行sql語句。

1 protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal();
2 protected static void setLocalPage(Page page) {
3         LOCAL_PAGE.set(page);
4 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM