JAVA基礎系列:ThreadLocal

1. 思路

    1. 什麼是ThreadLocal?
      ThreadLocal類顧名思義能夠理解爲線程本地變量。也就是說若是定義了一個ThreadLocal,每一個線程往這個ThreadLocal中讀寫是線程隔離,互相之間不會影響的。它提供了一種將可變數據經過每一個線程有本身的獨立副本從而實現線程封閉的機制。html

    2. 它大體的實現思路是怎樣的?
      Thread類有一個類型爲ThreadLocal.ThreadLocalMap的實例變量threadLocals,也就是說每一個線程有一個本身的ThreadLocalMap。ThreadLocalMap有本身的獨立實現,能夠簡單地將它的key視做ThreadLocal,value爲代碼中放入的值(實際上key並非ThreadLocal自己,而是它的一個弱引用)。每一個線程在往某個ThreadLocal裏塞值的時候,都會往本身的ThreadLocalMap裏存,讀也是以某個ThreadLocal做爲引用,在本身的map裏找對應的key,從而實現了線程隔離。面試

2. 圖解

2.1 位置

2.2 結構圖

  

2.3 源碼關係圖

2.4 內存關係圖

 

  

 

3. ThreadLocal和線程池

核心線程,銷燬線程,反作用(髒數據,內存溢出)安全

ThreadLocl 主要用於線程安全地共享某個變量
ThreadLocl 主要會產生髒數據和內存泄露。這兩個問題一般是在線程池的線程中使用ThreadLocal 引起的,由於線程池有線程複用和內存常駐兩個特色1.髒數據

   線程複用會產生髒數據。因爲線程池會重用Thread對象,那麼與Thread綁定的類靜態屬性也會被重用。
  若是在實現線程run() 方法中不顯示的調用remove() 清理與線程相關的ThreadLocal 信息。
  若是先一個線程不調用set() 設置初始值,那麼就get() 到重用信息,包括ThreadLocl 所關聯線對象的值。
2.內存泄露 在源碼註釋中提示使用static 關鍵字來修改ThreadLocal。
  在此場景下,寄但願於ThreadLocal對象失去引用後,觸發弱引用機制來回收Entry 的Value 就不現實了。
  在上例中,若是不進行remove() 操做,那麼這個線程執行完成後,經過ThreadLocal 對象持有的string對象是不會被釋放的。 以上兩個問題解決的辦法很簡單,就是每次用完ThreadLocal 時,必須調用remove() 方法清理。

 

參考網址併發

  1. ThreadLocal-面試必問深度解析
  2. Java 源碼解析實戰 - ThreadLocal 原理
  3. 【Java併發學習五】圖解ThreadLocal
  4. 完全理解ThreadLocal
  5. ThreadLocal源碼解讀
  6. 死磕Java之聊聊ThreadLocal源碼(基於JDK1.8)
  7. Java面試必問,ThreadLocal終極篇
  8. 2019/03面試題-併發爲主
  9. 深刻理解 ThreadLocal (這些細節不該忽略)
  10. https://www.iteye.com/topic/1123824
相關文章
相關標籤/搜索