ThreadLocal原始碼分析

2022-07-17 07:09:07 字數 2169 閱讀 8052

我們知道,程序是os分配資源的最小單位,而執行緒是執行操作的最小單位並不享有資源。threadlocal實現了執行緒資料變數的本地儲存,每個執行緒都儲存自己的變數,所有的執行緒都使用同樣的threadlocal物件來訪問變數,但是每個執行緒在訪問時看到的變數值是不同的,不會影響到其他執行緒的變數,並且值可以為null。

整個實現架構圖如下:

乙個執行緒可以持有多個threadlocal物件,每個threadlocal例項其實很輕量級,只儲存hashcounter分配給它的hash值和自身的乙個弱引用。訪問時只要將values裡的obj陣列複製當前方法的區域性變數中操作就可以了。

原來的jdk中,table是用map實現的;在1.7原始碼中使用了object陣列來存放,如圖間隔存放了kv;這樣做避開了執行緒併發的鎖操作,大大加快了訪問的速度。另外值得提一點的是,hashcounter每次分配給threadlocal物件的hash值都是偶數,這樣取得的index位置來存放threadlocal物件,index+1位置存放變數值,十分巧妙。

threadlocal類結構如下,我們接下來依次分析這些方法:

介紹完了整個架構,我們先不去看values這個靜態內部類,其實它維護了threadlocal到變數值的對映,乙個hashtable而已,回頭再來看它。

先來看一眼完成當前執行緒變數值的get方法:

public

t get()

} else

return (t) values.getaftermiss(this

); }

方法中,根據當前執行緒例項獲取到values,先來看看如果values為空會如何?

如果values為空則對其初始化,呼叫initializevalues方法:

/**

* creates values instance for this thread and variable type.

*/values initializevalues(thread current)

我們來看一下values的構造方法:

values()
通過initializetable方法來建立乙個object陣列,容量為32,mask值為0x1f。

private

void initializetable(int

capacity)

我們重新回到get方法中,方法最後返回getaftermiss(this),該方法將當前threadlocal傳入,並返回initialvalue()定義的值,這個方法是可以自定義重寫的。

threadlocal中其他的操作方法也是這樣。操作完成後,我們需要與values中的陣列互動,這裡就呼叫了put方法:

/**

* sets entry for given threadlocal to given value, creating an

* entry if necessary.

*/void put(threadlocal>key, object value)

if (k == null

)

//go back and replace first tombstone.

table[firsttombstone] =key.reference;

table[firsttombstone + 1] =value;

tombstones--;

size++;

return

; }

//remember first tombstone.

if (firsttombstone == -1 && k ==tombstone) }}

每次操作object陣列,都要先清理一下廢棄的元素。然後再進行元素存放。

總結threadlocal與values的組合設計實現了多個執行緒儲存本地變數而又互不干擾的功能,更令人叫絕的是通過固定hash值分配的方式,避開了鎖操作。關於values內部的object陣列的維護比較複雜,以後有機會再來研究補充。

ThreadLocal實現原理與原始碼分析

threadlocal底層實現內部類 threadlocalmap 一 threadlocal的set方法原始碼分析 1 public void set t value thread t thread.currentthread threadlocalmap map getmap t if map ...

ThreadLocal原始碼理解

threadlocal其實原理是建立了多份相同資料儲存在堆記憶體上,每個執行緒的thread類裡有threadlocal.threadlocalmap threadlocals的屬性來指向存位置,所以每個執行緒修改都不會影響到其他執行緒的資料 首先說下下面用到的東西 threadlocalmap為t...

ThreadLocal原始碼分析

在理解handler looper之前,先來說說threadlocal這個類,聽名字好像是乙個本地執行緒的意思,實際上它並不是乙個thread,而是提供乙個與執行緒有關的區域性變數功能,每個執行緒之間的資料互不影響。我們知道使用handler的時候,每個執行緒都需要有乙個looper物件,那麼and...