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不存在任何強引用,就會被回收器回收,避免內存泄漏。

clipboard.png

那麼問題來了,即使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.

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