ThreadLocal 是什麼?有哪些使用場景?

2021-09-26 21:31:41 字數 2406 閱讀 1258

threadlocal 是執行緒本地儲存,在每個執行緒中都建立了乙個 threadlocalmap 物件,每個執行緒可以訪問自己內部 threadlocalmap 物件內的 value。

經典的使用場景是為每個執行緒分配乙個 jdbc 連線 connection。這樣就可以保證每個執行緒的都在各自的 connection 上進行資料庫的操作,不會出現 a 執行緒關了 b執行緒正在使用的 connection; 還有 session 管理 等問題。

threadlocal 使用例子:

public class testthreadlocal

};public static void main(string args)

};t.start();}}

/*** 執行緒本地儲存變數加 5

*/private static void add10bythreadlocal() }}

列印結果:啟動了 3 個執行緒,每個執行緒最後都列印到 "threadlocal num=5",而不是 num 一直在累加直到值等於 15

thread-0 : threadlocal num=1

thread-1 : threadlocal num=1

thread-0 : threadlocal num=2

thread-0 : threadlocal num=3

thread-1 : threadlocal num=2

thread-2 : threadlocal num=1

thread-0 : threadlocal num=4

thread-2 : threadlocal num=2

thread-1 : threadlocal num=3

thread-1 : threadlocal num=4

thread-2 : threadlocal num=3

thread-0 : threadlocal num=5

thread-2 : threadlocal num=4

thread-2 : threadlocal num=5

thread-1 : threadlocal num=5

實現原理:

按照我們第一直覺,感覺 threadlocal 內部肯定是有個 map 結構,key 存了 thread,value 存了 本地變數 v 的值。每次通過 threadlocal 物件的 get() 和 set(t value) 方法獲取當前執行緒裡存的本地變數、設定當前執行緒裡的本地變數。

而 jdk 的實現裡面這個 map 是屬於 thread,而非屬於 threadlocal。threadlocal 僅是乙個**工具類,內部並不持有任何與執行緒相關的資料,所有和執行緒相關的資料都儲存在 thread 裡面。threadlocalmap 屬於 thread 也更加合理。

還有乙個更加深層次的原因,這樣設計不容易產生記憶體洩露。

threadlocal 持有的 map 會持有 thread 物件的引用,只要 threadlocal 物件存在,那麼 map 中的 thread 物件就永遠不會被**。threadlocal 的生命週期往往比執行緒要長,所以這種設計方案很容易導致記憶體洩露。

jdk 的實現中 thread 持有 threadlocalmap,而且 threadlocalmap 裡對 threadlocal 的引用還是弱引用(weakreference),所以只要 thread 物件可以被**,那麼 threadlocalmap 就能被**。jdk 的這種實現方案複雜但更安全。

在 finally **塊中手動清理 threadlocal 中的 value,呼叫 threadlocal 的 remove()方法。

threadlocal 核心方法

設定 thread 對應的 value 值,首次會建立乙個 threadlocalmap ,新增 threadlocal - value 到 threadlocalmap 中,並且繫結 threadlocalmap 到當前執行緒。

public void set(t value)

建立 threadlocalmap,繫結到當前執行緒。

void createmap(thread t, t firstvalue)

通過 threadlocalmap 獲取當前執行緒的儲存的 value 值  

public t get()

}return setinitialvalue();

}設定 threadlocal 的初始化值,未 set(t value) 初次獲取 thread 對應的 value 值時會呼叫,即被 setinitialvalue 方法呼叫。需要重寫該方法。

protected t initialvalue()

移除當前執行緒儲存的 value 值。當 threadlocal 不在使用,最好在 finally 語句塊中,呼叫 remove() 方法,釋放去 value 的引用,避免記憶體洩露。

public void remove()

ThreadLocal是什麼?怎麼用?

threadlocal用於儲存某個執行緒共享變數 對於同乙個static threadlocal,不同執行緒只能從中get,set,remove自己的變數,而不會影響其他執行緒的變數。簡單的使用 public class threadlocaltestpublic class mytest exte...

XML是什麼,有什麼作用

source xml即可擴充套件標記語言 extensible markup language 標記是指計算機所能理解的資訊符號,通過此種標記,計算機之間可以處理包含各種資訊的文章等。如何定義這些標記,既可以選擇國際通用的標記語言,比如html,也可以使用象xml這樣由相關人士自由決定的標記語言,這...

webpack是什麼,有什麼作用

直接解釋為 模組化打包機 或者 模組打包工具。首先,認為它是乙個工具,幫助我們更好的處理事情的。其次,打包 如何理解?假設我們需要寄快遞。我們將許多的物品都放進了乙個紙皮箱,然後進行封箱。這就是打包。對應到前端開發來說,就是將很多的的 css檔案,js檔案,等 物品 全都寫進乙個js檔案,而不是在乙...