java中ThreadLocal和ThreadLocalMap淺析
ThreadLocal和ThreadLocalMap
先發(fā)一個最常見的圖
關(guān)鍵字 ThreadLocal ThreadLocalMap Thread
1 概念 ThreadLocal
理解:ThreadLocal類用來設(shè)置線程私有變量 本身不儲存值 主要提供自身引用 和 操作ThreadLocalMap 屬性值得方法,使用ThreadLocal會通過ThreadLocal的引用定位到到堆中Thread的類ThreadLocalMap里散列表里的值 從而達(dá)到線程私有
目的:解決多線程使用共享對象的問題 空間換時間
2 存儲形式
ThreadLocalMap(ThreadLocal 的靜態(tài)內(nèi)部類 由ThreadLocal類來維護(hù)和創(chuàng)建)中
a:和普通Hashmap類似存儲在一個數(shù)組內(nèi),但與hashmap使用的拉鏈法解決散列沖突的是 ThreadLocalMap使用開放地址法 //開放地址法缺點(diǎn) : -空間利用率低 開發(fā)地址發(fā)會在散列沖突時尋找下一個可存入的槽點(diǎn) 為了避免沖突 負(fù)載因子會設(shè)置的相對較小 還使用的原因是 ThreadLocalMap的散列值均勻 且經(jīng)常增刪 純數(shù)組較方便 節(jié)點(diǎn)數(shù)量少 時也能節(jié)省掉指針域帶來的空間開銷
b : 數(shù)組 初始容量16,負(fù)載因子2/3
c : node節(jié)點(diǎn) 的key封裝了WeakReference 用于回收
d : 數(shù)組位置計算
ThreadLocalMap屬性
static class Entry extends WeakReference<ThreadLocal<?>> { Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } //初始容量16 private static final int INITIAL_CAPACITY = 16; //散列表 private Entry[] table; //entry 有效數(shù)量 private int size = 0; //負(fù)載因子 private int threshold;
ThreadLocalMap設(shè)置ThreadLocal 變量
private void set(ThreadLocal<?> key, Object value) { Entry[] tab = table; int len = tab.length; //與運(yùn)算 & (len-1) 這就是為什么 要求數(shù)組len 要求2的n次冪 //因?yàn)閘en減一后最后一個bit是1 與運(yùn)算計算出來的數(shù)值下標(biāo) 能保證全覆蓋 //否者數(shù)組有效位會減半 //如果是hashmap 計算完下標(biāo)后 會增加鏈表 或紅黑樹的查找計算量 int i = key.threadLocalHashCode & (len-1); // 從下標(biāo)位置開始向后循環(huán)搜索 不會死循環(huán) 有擴(kuò)容因子 必定有空余槽點(diǎn) for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get(); //一種情況 是當(dāng)前引用 返回值 if (k == key) { e.value = value; return; } //槽點(diǎn)被GC掉 重設(shè)狀態(tài) if (k == null) { replaceStaleEntry(key, value, i); return; } } //槽點(diǎn)為空 設(shè)置value tab[i] = new Entry(key, value); //設(shè)置ThreadLocal數(shù)量 int sz = ++size; //沒有可清理的槽點(diǎn) 并且數(shù)量大于負(fù)載因子 rehash if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }
3 儲存位置
儲存在Thread中的兩個ThreadLocalMap變量
4 儲存時機(jī)
threadLocals 在ThreadLocal對象方法get中去創(chuàng)建 也由ThreadLocal來維護(hù)
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else **createMap**(t, value); } void createMap(Thread t, T firstValue) { t.threadLocals = **new ThreadLocalMap**(this, firstValue); }
inheritableThreadLocals 和ThreadLocal類似 InheritableThreadLocal重寫了createMap方法
void createMap(Thread t, T firstValue) { t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue); }
inheritableThreadLocals 作用是將ThreadLocalMap傳遞給子線程
init方法中 條件滿足后直接為子線程創(chuàng)建ThreadLocalMap
重要
a: 僅在初始化子線程的時候會傳遞 中途改變副線程的inheritableThreadLocals 變量 不會將影響結(jié)果傳遞到子線程 。
b:使用線程池要注意 線程不回收 盡量避免使用父線程的inheritableThreadLocals 導(dǎo)致錯誤
到此這篇關(guān)于java中ThreadLocal和ThreadLocalMap淺析的文章就介紹到這了,更多相關(guān)ThreadLocal和ThreadLocalMap內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis中xml的動態(tài)sql實(shí)現(xiàn)示例
本文主要介紹了Mybatis中xml的動態(tài)sql實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06SpringBoot整合ElasticSearch實(shí)踐
本篇文章主要介紹了SpringBoot整合ElasticSearch實(shí)踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05Spring Boot中的屬性綁定的實(shí)現(xiàn)
這篇文章主要介紹了Spring Boot中的屬性綁定的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動生成相關(guān)文件的示例代碼
Mybatis-Plus是一個優(yōu)秀的Mybatis增強(qiáng)工具,目前更新到3.1.1,本文通過示例代碼給大家介紹SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動生成相關(guān)文件的問題,感興趣的朋友跟隨小編一起看看吧2021-12-12Java mockito單元測試實(shí)現(xiàn)過程解析
這篇文章主要介紹了Java mockito單元測試實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08特殊數(shù)據(jù)結(jié)構(gòu)之使用Java實(shí)現(xiàn)單調(diào)棧示例
這篇文章主要為大家介紹了特殊數(shù)據(jù)結(jié)構(gòu)之使用Java實(shí)現(xiàn)單調(diào)棧示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09Java多線程中線程池常見7個參數(shù)的詳解以及執(zhí)行流程
本文主要介紹了Java多線程中線程池常見7個參數(shù)的詳解以及執(zhí)行流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07springmvc實(shí)現(xiàn)json交互-requestBody和responseBody
本文主要介紹了springmvc實(shí)現(xiàn)json交互-requestBody和responseBody的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03