一、用法
threadlocal用於儲存某個執行緒共享變數:對於同乙個static threadlocal,不同執行緒只能從中get,set,remove自己的變數,而不會影響其他執行緒的變數。
1、threadlocal.get: 獲取threadlocal中當前執行緒共享變數的值。
2、threadlocal.set: 設定threadlocal中當前執行緒共享變數的值。
3、threadlocal.remove: 移除threadlocal中當前執行緒共享變數的值。
4、threadlocal.initialvalue: threadlocal沒有被當前執行緒賦值時或當前執行緒剛呼叫remove方法後呼叫get方法,返回此方法值。
package com.coshaho.reflect;
/*** threadlocal用法
* @author coshaho
* */
public class mythreadlocal
};public static void main(string args)
public static class myintegertask implements runnable
@override
public void run()else
}trycatch (interruptedexception e)
} }
}public static class mystringtask implements runnable
@override
public void run() else
trycatch (interruptedexception e)}}
}}
執行結果如下:
呼叫get方法時,當前執行緒共享變數沒有設定,呼叫initialvalue獲取預設值!
執行緒integertask1: 0
呼叫get方法時,當前執行緒共享變數沒有設定,呼叫initialvalue獲取預設值!
執行緒integertask2: 0
呼叫get方法時,當前執行緒共享變數沒有設定,呼叫initialvalue獲取預設值!
呼叫get方法時,當前執行緒共享變數沒有設定,呼叫initialvalue獲取預設值!
執行緒stringtask1: a
執行緒stringtask2: a
執行緒stringtask1: aa
執行緒stringtask2: aa
執行緒integertask1: 1
執行緒integertask2: 1
執行緒stringtask1: aaa
執行緒stringtask2: aaa
執行緒integertask2: 2
執行緒integertask1: 2
執行緒stringtask2: aaaa
執行緒stringtask1: aaaa
執行緒integertask2: 3
執行緒integertask1: 3
執行緒stringtask1: aaaaa
執行緒stringtask2: aaaaa
呼叫get方法時,當前執行緒共享變數沒有設定,呼叫initialvalue獲取預設值!
執行緒integertask2: 0
呼叫get方法時,當前執行緒共享變數沒有設定,呼叫initialvalue獲取預設值!
執行緒integertask1: 0
二、原理
執行緒共享變數快取如下:
thread.threadlocalmap<threadlocal,object>;
1、thread: 當前執行緒,可以通過thread.currentthread()獲取。
2、threadlocal:我們的staticthreadlocal變數。
3、object: 當前執行緒共享變數。
我們呼叫threadlocal.get方法時,實際上是從當前執行緒中獲取threadlocalmap<threadlocal,object>,然後根據當前threadlocal獲取當前執行緒共享變數object。
threadlocal.set,threadlocal.remove實際上是同樣的道理。
這種儲存結構的好處:
1、執行緒死去的時候,執行緒共享變數threadlocalmap則銷毀。
2、threadlocalmap鍵值對數量為threadlocal的數量,一般來說threadlocal數量很少,相比在threadlocal中用map鍵值對儲存執行緒共享變數(thread數量一般來說比threadlocal數量多),效能提高很多。
關於threadlocalmap<threadlocal,object>弱引用問題:
當執行緒沒有結束,但是threadlocal已經被**,則可能導致執行緒中存在threadlocalmap<null,object>的鍵值對,造成記憶體洩露。(threadlocal被**,threadlocal關聯的執行緒共享變數還存在)。
雖然threadlocal的get,set方法可以清除threadlocalmap中key為null的value,但是get,set方法在記憶體洩露後並不會必然呼叫,所以為了防止此類情況的出現,我們有兩種手段。
1、使用完執行緒共享變數後,顯示呼叫threadlocalmap.remove方法清除執行緒共享變數;
2、jdk建議threadlocal定義為private static,這樣threadlocal的弱引用問題則不存在了。
多執行緒 ThreadLocal
目錄 一 threadlocal 概述 1.1 threadlocal 是什麼 1.2 threadlocal 的作用 二 threadlocal 的使用和原始碼分析 2.1 threadlocal 如何使用 2.1.1 常見方法 2.1.2 使用示例 2.2 threadlocal 原始碼分析 2...
多執行緒 ThreadLocal
執行緒的變數副本 就像命名一樣 每個執行緒隔離。每個thread都有自己的threadlocalmap,threadlocalmap的底層是使用陣列 其中每個entry,它的key是threadlocal k,繼承自weakreference,也就是我們常說的弱引用型別,可以簡單地將它的key視作t...
Java多執行緒 ThreadLocal
threadlocal 是jdk 包提供的,它提供了執行緒本地變數,也就是如果你建立了乙個threadlocal 變數,那麼訪問這個變數的每個執行緒都會有這個變數的乙個本地副本。當多個執行緒操作這個變數時,實際操作的是自己本地記憶體裡面的變數,從而避免了執行緒安全問題。建立乙個threadlocal...