一張圖解決ThreadLocal

一張圖解決ThreadLocal

一、前言

年底梳理知識體系時,研究了一下ThreadLocal的源碼,整理了一張核心圖。
想着,都走到這一步了,那就寫一篇深度解讀的文章吧。看過我之前文章的小夥伴都知道,我寫博客,就喜歡寫點別人沒寫的。要麼就寫個結構比別人好的。什麼都不行,那就別寫了。自己留着看就好了。
然後發現了ThreadLocal源碼解讀ThreadLocal可能引起的內存泄露這樣的優秀文章(兩篇文章合起來,就更完整了),它把我要說的,差不多都說了。
所以,我就決定從精簡(一張圖)與認知過程兩方面,寫一篇輔助學習ThreadLocal的文章。

二、核心圖

不囉嗦,核心圖直接貼上。
在這裏插入圖片描述

根據核心圖,已經對ThreadLocal瞭然於心的小夥伴,可以拿着圖片,溜了溜了。
還想聽我談談,我對ThreadLocal認知過程的小夥伴,可以留下來看看。

三、認知過程

話說,那是一個夜黑風高的夜晚,我躺在。。。
咳咳咳。抱歉,串場了。
最早接觸ThreadLocal的時候,是在看面試教程的時候。我聽到講師balabala講了一通,最後我腦海給ThreadLocal的第一印象就是,一個確保線程安全的線程變量(同一個變量,但每個線程都獨立)。這個印象伴隨了我大半年,反正我在那大半年也沒用過。。。

後來,在一次看技術文章的時候,又看到了一篇ThreadLocal的介紹。通篇看下來,這篇文章說的內容,除了我學過的,就是總結了一句ThreadLocal可以簡單看成一個Map<Thread, Object>。當時的我,還欣喜若狂,我終於懂得ThreadLocal的原理了。

再後來,我在微信的技術公衆號中,看到ThreadLocal的內存泄漏問題。那篇文章把這個問題說得非常嚴重,搞得好像這個問題導致了二戰爆發那麼嚴重。如果不懂這個問題,就不配參加面試,不配呼吸這個世界的美好空氣。。。幸好當時沒人知道,我不懂這個東西。然後我就趁着午休的時間,速度翻了翻這篇文章。看完之後,腦海中的印象就是,ThreadLocal中的map的key是WeakReference,可能被清除,導致對應的value內存泄漏

在接下來的小半年裏,我也曾奇怪,如果ThreadLocal是一個Map<Thread, Object>,那爲什麼一個線程可以有多個ThreadLocal變量呢?爲什麼設置ThreadLocal變量時,還需要設置範型類型呢?

直到在學習另一個課程時,講師提到棧封閉-ThreadLocal,才知道之前的認識是錯誤的。其實每個線程都有一個Map<ThreadLocal, Object>,這也解釋了我之前的兩個問題。但是當時由於工作與課程比較緊,還是沒有查看源碼。終究還是與ThreadLocal隔層紗。

最近臨近年底,整理自己的知識體系。這次打算好好整理整理,所以就仔細閱讀了ThreadLocal的源碼。也知道之所以每個線程都有一個Map<ThreadLocal, Object>,是因爲Thread有一個ThreadLocalMap(ThreadLocal內部類)變量。進而總結出了上面的核心圖。

四、總結

之所以提到ThreadLocal的認識過程,其實是想表達:

  • 認識是螺旋前進的
  • 如無必要,不要過於追求認識的深度
  • 想法要周全,執行要堅決

第一條的意思是,我們對某個事物的認識,往往伴隨着正確&錯誤之間的遊走。但是認識是在不斷加深,變得更加全面的。
至於第二條,如果一開始我就強求看源碼,那一定是事倍功半的。那時候的我對範型,弱應用等都瞭解太淺,缺乏足夠的基礎,讓我一窺ThreadLocal的全貌。具體的反面教材,就是當時剛入Java坑的我,強行擼Spring源碼。。。檣櫓灰飛煙滅啊。。。
第三條,在自己有想法的時候,需要周全想法。如果有了決策結果,就應該去堅決地貫徹它。

不得不說,溫故而知新啊。

願與諸君共進步。

參考

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