ThreadLocal 原始碼賞析

2021-10-05 01:15:54 字數 2874 閱讀 8859

前面我們分析了 thread類的原始碼,有了前面的鋪墊,通過原始碼 理解threadlocal的秘密就容易多了。

threadlocal類 提供了 get/set執行緒區域性變數的實現,threadlocal成員變數與正常的成員變數不同,每個執行緒都可以通過 threadlocal成員變數 get/set自己的專屬值。threadlocal例項 通常是類中的私有靜態變數,常用於將狀態與執行緒關聯,例如:使用者id或事務id。

public

class

threadlocal

threadlocalmap getmap

(thread t)

void

createmap

(thread t, t firstvalue)

public t get()

}return

setinitialvalue()

;}public

void

remove()

/** * 與大部分 map 的實現相同,底層也是使用 動態陣列來儲存 鍵值對entry,也有rehash、resize等

* 操作

*/static

class

threadlocalmap

}// 看過 hashmap 或 concurrenthashmap 原始碼的同學 一定下面對這些**很眼熟

/** * 陣列初始容量

*/private

static

final

int initial_capacity =16;

/** * entry陣列,用於儲存 k, object v>鍵值對

*/private entry[

] table;

/** * entry元素數量

*/private

int size =0;

/** * 類似於 hashmap 擴容因子機制

*/private

int threshold;

// default to 0

private

void

setthreshold

(int len)

private

static

intnextindex

(int i,

int len)

private

static

intprevindex

(int i,

int len)

/** * 系列構造方法

*/threadlocalmap

(threadlocal<

?> firstkey, object firstvalue)

private

threadlocalmap

(threadlocalmap parentmap)}}

}/**

* 根據 threadlocal物件 獲取其對應的 entry例項

*/private entry getentry

(threadlocal<

?> key)

/** * 常規map實現類 的set()方法,只不過這裡的 key被規定為 threadlocal型別

*/private

void

set(threadlocal<

?> key, object value)

// 如果key為null,用新key、value覆蓋,同時清理歷史key=null的陳舊資料

if(k == null)

} tab[i]

=new

entry

(key, value)

;int sz =

++size;

// 若超過閥值,則rehashif(

!cleansomeslots

(i, sz)

&& sz >= threshold)

rehash()

;}/** * remove the entry for key.

*/private

void

remove

(threadlocal<

?> key)}}

/** * 調整當前table的容量。首先掃瞄整個容器,以刪除過時的條目,如果這不能充分縮小表的大小,

* 將進行擴容操作

*/private

void

rehash()

/** * 擴容為原容量的兩倍

*/private

void

resize()

else}}

// 設定新的閾值

setthreshold

(newlen)

; size = count;

table = newtab;}}

}

簡單畫個圖總結一下 threadlocal 的原理,如下。

最後強調一下 threadlocal的使用注意事項:

threadlocal 不是用來解決執行緒安全問題的,多執行緒不共享,不存在競爭!其目的是使執行緒能夠使用本地變數。

專案如果使用了執行緒池,那麼執行緒**後threadlocal變數要remove掉,否則執行緒池**執行緒後,變數還在記憶體中,可能會帶來意想不到的後果!例如tomcat容器的執行緒池,可以在***中處理:繼承 handlerinterceptoradapter,然後複寫 aftercompletion()方法,remove掉變數!!!

ThreadLocal原始碼理解

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

ThreadLocal原始碼分析

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

ThreadLocal 原始碼解讀

在正式讀 前先簡單介紹threadlocal的實現方式。每個執行緒都會有乙個threadlocalmap,只有在使用到threadlocal的時候才會初始化threadlocalmap。需要儲存的物件t會被放到entry裡面儲存在threadlocalmap的陣列中,entry是乙個鍵值對的資料結構...