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清除掉,這樣就會被垃圾回收器清理了。spa

爲何不將entry的value也設置爲弱引用呢,這是由於若是value是弱引用,執行GC後,若value被清除,那咱們永遠也拿不到ThreadLocal保存的數據了。線程

一般實踐中,咱們常把ThreadLocal作爲單例使用,由於咱們要保證key爲ThreadLocal的值全局都能訪問到。當不是單例使用狀況下,咱們要記得在不實用ThreadLocal時調用一下ThreadLocal.remove()方法,刪除key。help gc.code

相關文章
相關標籤/搜索