ThreadLocal深入理解

2021-08-22 00:23:01 字數 1464 閱讀 3213

通過每個執行緒維護一張threadlocalmap雜湊對映表,key為threadlocal弱引用,value是object本身。也就是說,threadlocal本身不存任何實際值,而是通過本身作為key,從threadlocalmap中獲取具體的值。

實際上,threadlocalmap儲存的是entry(這個是底層**實現,每個執行緒持有)的乙個陣列,通過threadlocalhashcode&(len-1)獲取陣列的游標i,具體如下

private

void

set(threadlocal key, object value)

if (k == null)

}tab[i] = new entry(key, value);

int sz = ++size;

if (!cleansomeslots(i, sz) && sz >= threshold)

rehash();

}

由於entry使用弱引用關聯threadlocal物件,而執行緒堆疊內的是使用強引用關聯threadlocal物件,當執行緒堆疊中的引用釋放,遇到下次gc,threadlocal將被釋放,也就是說,entry的key將變成null,但此時實際的object還是沒有被釋放,一直在堆記憶體裡面,如果該執行緒一直沒結束,那這塊記憶體就將一直不能被**。

解決在threadlocal設計中,方法get(),set(),remove()的時候都會清除執行緒threadlocalmap裡所有key為null的value。

但是還是無法完全保證記憶體洩漏問題,例如threadlocal宣告稱類成員靜態變數,也就是說threadlocal的引用分配在了方法區,這種導致強引用一直會存放在類方法區,無法**threadlocal例項,這種情況可能會導致記憶體洩漏,具體可以參見threadlocal記憶體洩漏例項

threadmap為什麼要用弱引用

為什麼使用弱引用而不是強引用?

to help deal with very large and long-lived usages, the hash table entries use weakreferences for keys.(官網)

因此,threadlocal記憶體洩漏的根源是:由於threadlocalmap的生命週期跟thread一樣長,如果沒有手動刪除對應key就會導致記憶體洩漏,而不是因為弱引用。

每次使用完threadlocal,都呼叫它的remove()方法,清除資料。

參考:

ThreadLocal深入理解

threadlocal從字面上理解,很容易會把threadlocal誤解為乙個執行緒的本地變數。threadlocal並不是代表當前執行緒,threadlocal其實是採用雜湊表的方式來為每個執行緒都提供乙個變數的副本。從而保證各個執行緒間資料安全。每個執行緒的資料不會被另外執行緒訪問和破壞。每個執...

深入理解ThreadLocal

threadlocal例項為每乙個訪問它的執行緒 即當前執行緒 都關聯了乙個該執行緒的執行緒特有物件 執行緒特有物件 tso,thread specific object 各個執行緒建立各自的例項,乙個例項只能被乙個執行緒訪問的物件就被稱為執行緒特有物件,相對應的執行緒就被稱為該執行緒特有物件的持有...

深入理解threadlocal

threadlocal,很多地方叫做執行緒本地變數,也有些地方叫做執行緒本地儲存,其實意思差不多。可能很多朋友都知道threadlocal為變數在每個執行緒中都建立了乙個副本,那麼每個執行緒可以訪問自己內部的副本變數。這句話從字面上看起來很容易理解,但是真正理解並不是那麼容易。我們還是先來看乙個例子...