ThreadLocal的作用和實現原理

2021-08-26 20:34:53 字數 2995 閱讀 8343

threadlocal是乙個執行緒內部的資料儲存類,通過它可以在指定的執行緒中儲存資料,資料儲存以後,只有在指定的執行緒中可以獲取到儲存的資料,對於其他執行緒來說則無法取到資料。

threadlocal的主要作用

輕鬆實現一些看起來很複雜的功能,適合以下一些應用場景。

某些資料是以執行緒為作用域並且不同執行緒具有不同的資料的副本時,就可以考慮用threadlocal

例如:android中,handler需要獲取當前執行緒的looper,很顯然looper的作用域是執行緒並且不同執行緒具有不同的looper。

複雜邏輯下的物件傳遞,比如***的傳遞,有些時候乙個執行緒中的任務過於複雜,我們又需要***能夠貫穿整個執行緒的執行過程。

threadlocal的使用示例

threadlocalmbooleanthreadlocal = new threadlocal<>();

mbooleanthreadlocal.set(true);

log.d("@@@", "[thread@main]mbooleanthreadlocal = " + mbooleanthreadlocal.get());

new thread("thread@1")

}.start();

new thread("thread@2")

}.start();

輸出的日誌如下

d/@@

@: [thread@main]mbooleanthreadlocal = true

d/@@

@: [thread@1]mbooleanthreadlocal = false

d/@@

@: [thread@2]mbooleanthreadlocal = null

在上面示例**中,主線程的mbooleanthreadlocal的值設定為true,子執行緒1的mbooleanthreadlocal的值設定為false,子執行緒2的mbooleanthreadlocal的值不設定。

從日誌可以看出,雖然在不同執行緒中訪問同乙個threadlocal物件,但是他們通過threadlocal獲取到值卻是不一樣的,這就是threadlocal的神奇之處。

threadlocal是乙個泛型類,定義為public class threadlocal,只要弄清楚threadlocal的get方法和set方法,就可以明白它的實現原理。

threadlocal的set方法(android api 26),原始碼如下

public

void

set(t value)

從set原始碼可以看出,首先getmap方法來獲取當前執行緒的threadlocalmap,這個map是乙個自定義的hash map,key是theadlocal,value是對應儲存的值。

threadlocal的get方法(android api 26),原始碼如下

public t get() 

}return setinitialvalue();

}

從get原始碼可以看出,首先也是一樣用getmap方法來獲取當前執行緒的threadlocalmap,然後根據key=當前threadlocal來獲取對應的value值。

從threadlocal的set和get方法可以看出,它們所操作的都是當前執行緒的threadlocalmap物件。

因此在不同執行緒中,訪問同乙個threadlocal的set和get方法,它們對threadlocalde的讀、寫操作僅限於各自執行緒的內部,從而使threadlocal可以在多個執行緒中互不干擾地儲存和修改資料。

獲取當前執行緒的looper

在looper類中,定義了乙個threadlocal靜態常量

static

final threadlocalsthreadlocal = new threadlocal();

1、初始化looper,即呼叫looper.perpar(),原始碼如下

private

static

void

prepare(boolean quitallowed)

sthreadlocal.set(new looper(quitallowed));

}private

looper(boolean quitallowed)

從原始碼可以看到,在乙個執行緒中初始化looper,是用threadlocal儲存looper物件。同時保證乙個執行緒只擁有乙個looper,否則在初始化會報錯

only one looper may be created per thread

2、獲取當前執行緒的looper,即looper.mylooper(),原始碼如下

public

static @nullable looper mylooper()

從原始碼可以看到,返回looper物件是呼叫threadlocal.get(),即當前執行緒對應的looper物件。

我們可以根據此,判斷當前執行緒是否是主線程

public

boolean

ismainthread()

另外,handler也用來判斷當前執行緒是否有looper,否則報錯can』t create handler inside thread that has not called looper.prepare()

mlooper = looper.mylooper();

if (mlooper == null)

參考

任玉剛的《android開發藝術探索》

ThreadLocal的作用和原理

threadlocal是用來建立當前執行緒的區域性變數的類,建立的變數只能被當前執行緒訪問和修改 原理 set方法的原理 1.首先獲取當前執行緒物件 2.利用當前執行緒獲取threadlocalmap物件 3.如果threadlocalmap物件不為空,則設定值,否則建立這個map物件並設定值 由此...

ThreadLocal作用,原理

threadlocal一般被稱為執行緒池本地變數或執行緒本地儲存。起作用是為 當前執行緒 提供乙個臨時持有和傳遞物件的方法。由同乙個執行緒鎖執行的 只要持有同乙個threadlocal物件的引用,就都能訪問到與當前執行緒繫結的同乙個資料物件。threadlocal的內部宣告乙個自動定義的thread...

ThreadLocal的作用與使用

在我們程式設計時,如果遇到多個執行緒訪問同乙個變數應該怎樣實現?有人說使用同步。是的同步可以解決這種問題,但它是有弊端的,涉及到何時加鎖與釋放鎖等並且執行緒訪問鎖時需要等待,這樣很浪費時間。有乙個更好的方案就是使用threadlocal工具類,之前參加了乙個專案,本專案涉及到分庫,在業務進行中需要根...