ThreadLocal原始碼分析

2023-01-07 08:51:01 字數 2503 閱讀 8436

一、概念

threadlocal提供執行緒本地變數。這些變數與普通變數不同,每個執行緒有自己的乙份拷貝。threadlocal例項典型用法是在類中作為私有的靜態域,用與執行緒繫結狀態(比如,使用者id或者事務id)。

簡而言之,每個執行緒第一次獲取該值後,之後**程內部就可以隨意操作該變數,但是這並不影響其他執行緒,因為每個執行緒一旦擁有了該變數後,就會有乙份拷貝。

public class threadid ;

// returns the current thread's unique id, assigning it if necessary

public static int get()

}這是threadlocal文件中的乙個例子。

二、 主要api

threadlocal有get、set、remove用於設定變數值,還有受保護的initialvalue用於返回當前執行緒初值,如果開發者不覆寫該方法,那麼預設返回null。initialvalue一般只會呼叫一次,在呼叫get或set方法時呼叫,但是如果在呼叫remove之後再呼叫get就會又觸發initialvalue。

三、 原始碼分析

get()方法

threadlocal的get()方法用於獲取本執行緒儲存在threadlocal中的變數,其實現如下:

public t get()

呼叫setinitialvalue()設定初始值

return setinitialvalue();

}從上面的get()方法可以看出大體流程:

1. 根據當前執行緒取得threadlocalmap,如果不存在map,那麼呼叫setinitialvalue()建立map並設定初始值;

2. 如果map不為null,那麼從map中得到entry,如果entry為null,呼叫setinitialvalue()方法設定初始值;

3. 如果entry不為null,那麼就返回值即可。

當map不存在或者entry不存在時,將會呼叫setinitialvalue()方法,下面是setinitialvalue()方法的實現:

private t setinitialvalue()

可以看到setinitialvalue()方法在map不存在的時候會建立表,而在map存在的時候,就會設定初始值。

那麼下面先看一下是如何建立map的,並且這個map到底是什麼樣子的。

void createmap(thread t, t firstvalue)

可以看到createmap()方法建立了乙個threadlocalmap物件,並將threadlocalmap物件賦給了thread的threadlocals變數,所以可以得出每乙個執行緒都有乙個threadlocalmap物件,用於儲存每乙個執行緒的本地變數,map只有乙個,但是卻可以儲存多個本地變數。

既然createmap()就是給thread的threadlocals賦值,那麼可以猜測從執行緒中得到map就是獲取這個變數,下面是getmap()的實現,

threadlocalmap getmap(thread t)

可以看到,該方法果然如我們所想,就是返回thread的threadlocals變數。

至此,我們分析完了threadlocal的get()方法,其中的關鍵就是threadlocalmap,這個類後面會具體分析,看它是如何實現的。

set(t value)方法

set()方法用於設定當前執行緒的本地變數值,其實現如下:

public void set(t value)

經過了上面的get()方法,可以看出set()方法的流程是如出一轍的:

1. 如果thread的threadlocals變數不為null,那麼就直接將值設定;

2. 如果thread的threadlocals變數為null,那麼建立threadlocalmap並賦值給threadlocals變數。

remove()

remove()方法用於刪除當前執行緒的本地變數,其實現如下:

public void remove()

可以看到也是呼叫了threadlocalmap的remove()方法。

threadlocal的get()、set()和remove()方法最終都是委託給了threadlocalmap的相應方法,下面我們就著重分析一下threadlocalmap是如何實現的。

threadlocalmap原始碼分析

threadlocalmap是乙個自定義的hashmap,用於儲存執行緒本地變數。

構造方法

createmap()中呼叫threadlocalmap的構造方法,其實現如下:

threadlocalmap(threadlocal<?> firstkey, object firstvalue)

可以看到threadlocalmap的初始化完成的是entry陣列的建立,預設初始容量16,但是閾值的設定與hashmap有些不同,hashmap採用的載入因子預設是0.75,而setthreshold()方法如下:

private void setthreshold(int len) {

threshold = len * 2 / 3;

ThreadLocal工作原理 部分原始碼分析

1.大概去 看 threadlocal 其根本實現方法,是在thread裡面,有乙個屬性 threadlocals null threadlocalmap 靜態內部類維護了乙個entry 陣列 1private entry table 檢視entry 原始碼,它維護了兩個屬性,threadlocal...

vb購物車原始碼

public class form1 dim total as integer private sub combobox1 selectedindexchanged byval sender as byval e as handles select case case is 服裝 幸福羊毛衫 幸福男...

FLASH游標跟隨原始碼

滑鼠跟隨 紹興 導航 滑鼠跟隨 物體對滑鼠的跟隨可以採用在幀上新增as語句stardrag的方法來實現。但是採用這種方法所實現的跟隨過程太生硬,跟得實在是緊,也就是當滑鼠移動到別的位置,物體也很快的移動了過來,假如要讓物體慢慢 速度可以控制 的靠近滑鼠,使用stardrag這條語句就不能做到。慢慢靠...