Adobe出品的專門為Web開發者設計的跨平臺開源編輯器Brackets
1,ThreadLocal是什麼:
ThreadLocal也是解決多執行緒訪問共享變數問題的,不同於加鎖,他會在每一個執行緒內部建立副本,
每個執行緒獨立訪問自己內部的副本,不會產生衝突。
2,用法:
public class ThreadLocalTest { static ThreadLocal<String> localVar = new ThreadLocal<>(); static void print(String str) { //列印當前執行緒中本地記憶體中本地變數的值 System.out.println(str + " :" + localVar.get());View Code//清除本地記憶體中的本地變數 localVar.remove(); } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { //設定執行緒1中本地變數的值 localVar.set("localVar1"); //呼叫列印方法print("thread1"); //列印本地變數 System.out.println("after remove : " + localVar.get()); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { //設定執行緒1中本地變數的值 localVar.set("localVar2");//呼叫列印方法 print("thread2"); //列印本地變數 System.out.println("after remove : " + localVar.get()); } }); t1.start(); t2.start(); } }
3,原理:
ThreadLocal類:
①內部類:ThreadLocalMap
是一個雜湊表,迴圈陣列+開發地址法中線性探測法解決雜湊衝突。
什麼意思呢?試試想一下:線性探測法會在陣列中形成以null隔開的若干‘塊’,我們把它類比成拉鍊法裡面的每一個連結串列。
線性探測法在一個快中(快可能未null)新增元素就相當於尾插法,刪除元素,就要調整該快中,被刪除元素之後的元素,要前移
保證他們下次能被探測到。就緒拉鍊法裡面的調整指標關係。
Entry陣列儲存的是key-value鍵值對,key是ThreadLocal,value是Object物件。
- 引數:
- 方法:主要是雜湊表的,增刪改查
①增刪改查之前,首先要介紹一下expungeStaleEntry()函式,顧名思義刪除元素用的
②getEntry():
getEntryAfterMiss():
③set()函式:
replaceStaleEntry()
cleanSomeSlots();
④remove()
⑤rehash()
expungeStaleEntries()
resize()擴容:
總結:ThreadLocalMap(),雜湊表,陣列+線性探測法解決雜湊衝突。初始容量16,擴容*2.
在增刪改查中不停清理,失效的TreadLocal元素。
記憶體洩漏問題:
<1>ThreadLocalMap的Entry陣列是key為ThreadLocal的弱引用,而valve是強引用。如果ThreadLocal物件沒有被外部強引用,垃圾回收時,key被回收
為null但是value還在。造成記憶體洩漏。
<2>雖然ThreadLocalMap在get(),set()函式裡多次清理key為null的失效元素,但是當沒有呼叫get(),set()時,不會清理。
解決方法:<1>使用完ThreadLocal後手動呼叫remove方法。
<2>將ThreadLocal定義為private static 隨執行緒一起消亡。
②看完ThreadLocalMap,在回到ThreadLocal類,
- set()
- get()
map空就初始化map
- 雖然ThreadLocalMap是ThreadLocal內部類,但ThreadLocal裡並沒有ThreadLocalMap引數,
而是通過getMap()方法;獲得執行緒的threadlocalS。
呼叫getMap的地方也是傳入當前執行緒的
進入Thread類:
ThreadLocalMap例項化在Thread類裡作為引數。即每一個執行緒有一個,哈西表,threadlocals,顧名思義用來存放該
執行緒ThreadLocals變數的。
ThreadLocal是ThreadLocalMap的封裝,提供了set(),get();看起來是每個Threadlocal變數單獨get(),set()。背後還是通過每個Thred的
ThredLocalMap統一管理所有ThreadLocal變數;
參考:
https://www.cnblogs.com/fsmly/p/11020641.html
https://baijiahao.baidu.com/s?id=1653790035315010634&wfr=spider&for=pc
https://www.jianshu.com/p/80866ca6c424
https://blog.csdn.net/ywlmsm1224811/article/details/91388109