如今稍微大點的公司面試,可能會問到ThreadLocal源碼實現,不過在介紹它以前,咱們先介紹JVM中引用的概念。所謂這些概念就是我所說的基礎了。引用強弱關係到內存垃圾回收時機,用好引用能夠減輕內存壓力。JVM引用一共分爲4種,分別是強引用,軟引用,弱引用和虛引用。面試
如上圖:根引用list指向堆,一直向list添加512K的字節數組,程序幾秒後會出現堆溢出,代碼中list引用稱爲強引用。強引用內存一直不會被釋放,直到內存溢出。數組
如上圖代碼:主函數中,軟引用須要用SoftReference包裝user對象,運行程序先配置初始化參數,-Xmx10M 設置堆空間爲10m,設置user=null,user引用消失,主函數第一次調用GC時,控制檯輸出User對象信息,說明堆中User對象還存在,user對象並無被回收,這是由於軟引用softRef指向堆中User 對象,申請內存byte[] bytes = new byte[1024*985*6];bytes 約6M,bytes引用對象會進入老年代,此時老年代會GC,此時控制檯會輸出null,說明此時userRef失去引用,堆中的user對象都被當成垃圾回收了。爲何要設置bytes 約6M,是由於想測試一個結論:當內存不足時,GC會回收軟引用。緩存
特別注意:調試時,985設置bytes引用執行堆內存的大小,須要本身調試,纔可能出現上述結果。安全
如上圖代碼:弱引用對象須要用WeakReference包裝,GC後,弱引用對象被回收。總結一句:當GC時,無論內存夠不夠,弱引用會被回收。咱們的ThreadLocal就是被WeakRefernece包裝。微信
小結下:強引用,軟引用,弱引用,虛引用的生命力是從高往低的。生命力越低越容易被回收,強引用則沒法被回收,軟引用比較適用於緩存的場景,軟引用只有內存緊張時纔會被回收,弱引用只要發生GC會被回收。ide
ThreadLocal是線程安全的,由於它能讓每一個線程都擁有本身獨享變量。它也可讓一個線程擁有多個變量。底層使用hash表實現的數組,說白了就是一個HashMap,其中key是ThreadLocal,value就是值。使用起來很方便。函數
如上圖代碼:建立一個ThreadLocal,當調用set時,主線程就擁有了本身的私有變量「叫練」了,經過get就能夠取出來。但這裏有個問題,源碼中ThreadLocal是被WeakReference包裝的。爲何要這麼作!這樣作的目的是爲了節約內存,下面咱們詳細瞭解下!學習
我問本身下面幾個問題:測試
不會,當線程結束,ThreadLocal纔有可能回收,注意是有可能,由於還有其餘的線程引用了當前ThreadLocal。spa
防止內存泄漏,爲了回收內存。
由於Entry中的value多是一個對象,而這個對象可能被其餘線程引用,一旦設置Entry爲WeakReference,可能致使其餘線程空指針。
每次使用完ThreadLocal以後,須要調用remove方法,清除當前線程的threadLocal。
學習不是一蹴而就的,你們看若是你不去了解JVM引用,你就沒法搞清楚ThreadLocal源碼。好了,文章有地方還寫的不清晰但願親們加以指正和點評,喜歡的請點贊加關注哦。點關注,不迷路,我是叫練,邊叫邊練,公衆號【叫練】,微信號【jiaolian123abc】。