首頁>技術>

我們知道,當多個執行緒訪問同一個變數時特別容易出現併發問題,特別是多個執行緒在對一個變數同時操作時。所以為了執行緒安全,一般是採用同步訪問該資源。在實際程式碼中,我們一般會用synchronized、ReentrantLock ,甚至是分散式鎖這些鎖來實現同步操作。

不過今天要介紹的是ThreadLocal,這個類線上程安全方面是怎麼實現的呢,帶著這個問題帶來今天的文章。

先來一段程式碼開始今天的分析, 如下:

這段程式碼,df是一個公共的變數,有兩個執行緒one和two都在訪問它,並通過set方法修改裡面的值,然後執行,結果永遠如下:

thread tow's value is : this is thread two

thread one's value is :this is thread one

至於打印出來的順序,這個其實是無所謂的,因為執行緒的執行你應該是了解的。

那接下來就分析下這個結果為什麼永遠會是這樣,而不是出現如下結果:

thread tow's value is : this is thread one

thread one's value is :this is thread two

接下來從原始碼層進行分析,set方法如下:

邏輯很好理解,先從may裡獲取,獲取到則進行設值

沒獲取到,建立map並進行設值。

首先開啟看下get這個方法,如下:

簡單吧,其實就是獲取了當前執行緒的一個內部屬性而已,這個屬性的型別是

ThreadLocalMap。

再看一下createMap的方法,如下:

也很簡單,其實就是把當前執行緒的屬性賦值操作而已。

ThreadLocalMap從命名上也可以大概看出是個特殊的Map,這裡不專門展開,後續有時間詳細分析一下這個類。

從程式碼上看出,在create的時候,僅僅是修改當前執行緒的屬性:threadLocals,既然成員屬性的話,那說明此塊記憶體屬於當前執行緒獨享(記憶體模式後面抽個專題詳細的講述,當前只需要知道執行緒獨享分配給自己的那塊記憶體即可),從而也就說明這個操作是執行緒安全的。

從而也就說明,在get的時候獲取到的值就是當前執行緒的成員變數。

從以上程式碼可以看出,ThreadLocal其實就是操作執行緒的一個殼子而已,對執行緒API較為熟悉的話,自己也是可以寫出來的,只是我們作為使用者,站在巨人的肩膀上看的更高而已。

對於初學者來說,不能僅知道為什麼是像別人的講的那樣,還是需要多看看原始碼自己加深一下印象,對自己是有好處的。

23
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 「騰訊開源Tars」c++ RPC 框架:服務釋出