ThreadLocal的源碼深入探究

ThreadLocal的源碼深入探究

引言:

週五去面試又被面試的一個問題問啞巴了

面試官:知道ThreadLocal的作用是什麼嗎?

我:ThreadLocal可以把創建的變量只能被當前線程訪問

面試官:那ThreadLocal是怎麼保證把創建的變量只能被當前線程訪問呢?

我:。。。(啞巴了)

在這之前我只記住了ThreadLocal可以把創建的變量只能被當前線程訪問這個結論,但是至於ThreadLocal為什麼可以把創建的變量只能被當前線程訪問卻從來沒有去想過。

先說結論: ThreadLocal的實現原理就是用了ThreadLocal裡面的一個靜態ThreadLocalMap

這個是怎麼操作的呢,往下看

ThreadLocalMap是ThreadLocal裡面的一個靜態類

源碼如下所示

ThreadLocal的源碼深入探究

ThreadLocalMap是Thread裡面的一個屬性

為什麼這樣說呢,首先我們看到Thread類裡面有一個屬性就叫做ThreadLocalMap

ThreadLocal的源碼深入探究

然後我們看一下ThreadLocal裡面的set()方法,看到源碼可以看到噹噹前線程的ThreadLocalMap是null的時候,此時就會走下面的紅色框裡面的代碼

ThreadLocal的源碼深入探究

然後就是會走下面的方法,然後new一個ThreadLocalMap賦值給當前線程的threadLocals這個變量,threadLocals這個變量在Thread裡面就是ThreadLocal.ThreadLocalMap類型的

ThreadLocal的源碼深入探究

然後當set()的時候,會把當前實例化對象的ThreadLocal作為key值,然後把set()裡面的參數當成value放到這個ThreadLocalMap裡面

在ThreadLocal裡面源碼set(),此時可以看到set()的源碼就是首先獲取當前線程,然後利用當前線程獲取一個ThreadLocalMap的對象,然後如果ThreadLocalMap對象為空,則把當前ThreadLocal當成key,set()裡面的參數當成value放到ThreadLocalMap集合裡面,否則創建這個ThreadLocalMap對象,然後把當前ThreadLocal當成key,set()裡面的參數當成value放到ThreadLocalMap集合裡面

ThreadLocal的源碼深入探究

上面的createMap(t,value)源碼如下

ThreadLocal的源碼深入探究

看到上面的代碼之後,我們也能知道為什麼ThreadLocal可以把創建的變量只能被當前線程訪問,其他線程則無法訪問和修改,因為ThreadLocal的值是放入了當前線程的一個ThreadLocalMap實例中,所以只能在本線程中訪問,其他線程無法訪問。

Jdk1.8的ThreadLocalMap

看源碼發現在jdk1.8裡面,ThreadLocalMap裡面是用Entry[]這個數組來實現ThreadLocalMap的功能。使用過程是:Entry類裡面的key值就是ThreadLocal,並且是弱引用,然後Entry類裡面的value屬性對應放入到ThreadLocalMap調用set方法裡面的第二個參數

看代碼:下面是 jdk1.8裡面的ThreadLocalMap類裡面的set方法,然後下面的紅色框裡面的使用的就是Entry類

ThreadLocal的源碼深入探究

Entry類就是指ThreadLocalMap類裡面的Entry類,如下所示

ThreadLocal的源碼深入探究

然後我們看一下ThreadLocalMap裡面的set()方法是怎麼進行存儲的

首先可以看到下面的紅色框裡面的threadLocalHashCode就是獲取當前ThreadLocal實例對象的threadLocalHashCode屬性,這個threadLocalHashCode屬性就是唯一的,它是怎麼來的呢,看下面的圖片,首先是ThreadLocal類裡面的HASH_INCREMENT常量,然後通過下面的nextHashCode()方法來進行原子性的增加1,然後把nextHashCode()方法的返回值給當前的ThreadLocal實例化對象的threadLocalHashCode屬性,這樣就保證唯一性了

ThreadLocal的源碼深入探究

然後把這個ThreadLocal的threadLocalHashCode值當成ThreadLocalMap類裡面的Entry數組的索引值,就是下面的綠色框裡面的代碼,這樣就把ThreadLocal調用的set()方法的兩個參數都存儲到ThreadLocalMap裡面的Entry數組裡面了

ThreadLocal的源碼深入探究

到此ThreadLocal的源碼探究就結束了,眼前閱讀的讀者您懂了嗎,有什麼不清楚的,歡迎留言,一起探究啊

最後送上福利一張

ThreadLocal的源碼深入探究


分享到:


相關文章: