ThreadLocal的理解
Thread有一個 ThreadLocal.ThreadLocalMap 型別的threadLocals成員變數,他是一個map,底層是一個 ThreadLocalMap.Entry 的陣列,每個 ThreadLocal 變數都有一個 threadLocalHashCode ,根據這個hashcode可計算出當前ThreadLocal在陣列的index值。
ThreadLocalMap.Entry是一個弱引用型別 WeakReference<ThreadLocal<?>> ,Entry的value就是我們需要儲存的物件,而key則是一個弱引用的referent,當 ThreadLocal 沒有任何強引用時,GC後即使還有弱應用存在也會被回收,這時Entry的key為null。所以即使執行緒一直活著,只要ThreadLocal不存在任何強引用,就會被回收器回收,避免記憶體洩漏。
那麼問題來了,即使Entry的key為弱引用會被回收,但value一直以key為null的Entry儲存在map中,這是強引用,永遠不會被回收。 ThreadLocalMap 的解決方法是在每次get、set、remove時都會將key為null的entry清除掉,這樣就會被垃圾回收器清理了。
為什麼不將entry的value也設定為弱引用呢,這是因為如果value是弱引用,執行GC後,若value被清除,那我們永遠也拿不到ThreadLocal儲存的資料了。
通常實踐中,我們常把ThreadLocal做為單例使用,因為我們要保證key為ThreadLocal的值全域性都能訪問到。當不是單例使用情況下,我們要記得在不實用ThreadLocal時呼叫一下ThreadLocal.remove()方法,刪除key。help gc.