java ThreadLocal?類常用方法源碼解析
以下是 ThreadLocal 類常用方法源碼解析:
1. get()
獲取當(dāng)前線程的 ThreadLocal 變量的值。如果變量尚未被當(dāng)前線程設(shè)置,則返回 null。
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
解釋:該方法首先獲取當(dāng)前線程 Thread.currentThread()
。
然后,調(diào)用 getMap(t)
方法獲取當(dāng)前線程的 ThreadLocalMap
對象 map
。
如果 map
不為 null
,表示當(dāng)前線程已經(jīng)有一個 ThreadLocalMap
,可以嘗試獲取與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。
調(diào)用 map.getEntry(this)
方法,傳入當(dāng)前 ThreadLocal
對象作為參數(shù),獲取與之關(guān)聯(lián)的 Entry
節(jié)點(diǎn) e
。
如果 e
不為 null
,表示找到了與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。通過強(qiáng)制類型轉(zhuǎn)換將 e.value
轉(zhuǎn)換為泛型類型 T
,并將其賦值給 result
變量。
最后,返回 result
,即當(dāng)前線程中與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。
如果 map
為 null
或者未找到與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值,則調(diào)用 setInitialValue()
方法來設(shè)置初始值,并返回該值。
總之,get()
方法用于獲取當(dāng)前線程中與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。它首先獲取當(dāng)前線程的 ThreadLocalMap
對象,然后在該對象中查找與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。如果找到了值,則返回該值;否則,設(shè)置初始值并返回。
2. set(T value)
該方法用于將指定的值 value
關(guān)聯(lián)到當(dāng)前線程中的當(dāng)前 ThreadLocal
對象。
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
解釋:該方法首先獲取當(dāng)前線程 Thread.currentThread()
。
然后,調(diào)用 getMap(t)
方法獲取當(dāng)前線程的 ThreadLocalMap
對象 map
。
如果 map
不為 null
,表示當(dāng)前線程已經(jīng)有一個 ThreadLocalMap
,可以直接調(diào)用 map.set(this, value)
方法將當(dāng)前 ThreadLocal
對象和指定的值 value
關(guān)聯(lián)起來。
如果 map
為 null
,表示當(dāng)前線程還沒有 ThreadLocalMap
,需要調(diào)用 createMap(t, value)
方法來創(chuàng)建一個新的 ThreadLocalMap
并將其與當(dāng)前線程關(guān)聯(lián)起來。
總之,set(T value)
方法用于將指定的值關(guān)聯(lián)到當(dāng)前線程中的當(dāng)前 ThreadLocal
對象。它首先獲取當(dāng)前線程的 ThreadLocalMap
對象,然后根據(jù)是否存在該對象來選擇直接設(shè)置值或創(chuàng)建新的 ThreadLocalMap
對象。
3. remove()
該方法用于從當(dāng)前線程的 ThreadLocalMap
中移除與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。
public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); }
解釋:該方法首先通過調(diào)用 getMap(Thread.currentThread())
方法獲取當(dāng)前線程的 ThreadLocalMap
對象 m
。
如果 m
不為 null
,表示當(dāng)前線程有一個 ThreadLocalMap
對象,可以調(diào)用 m.remove(this)
方法來移除與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。
如果 m
為 null
,表示當(dāng)前線程沒有 ThreadLocalMap
對象,無需進(jìn)行任何操作。
總之,remove()
方法用于從當(dāng)前線程的 ThreadLocalMap
中移除與當(dāng)前 ThreadLocal
對象關(guān)聯(lián)的值。它首先獲取當(dāng)前線程的 ThreadLocalMap
對象,然后根據(jù)是否存在該對象來選擇是否進(jìn)行移除操作。
4. initialValue()
該方法用于提供一個初始值,以便在首次訪問 ThreadLocal
對象時使用。
protected T initialValue() { return supplier.get(); }
解釋:該方法調(diào)用了一個 supplier.get()
方法來獲取初始值。這里的 supplier
是一個 Supplier<T>
類型的對象,它提供了一個無參數(shù)的 get()
方法,用于獲取初始值。
通過重寫 initialValue()
方法,我們可以自定義初始值的生成邏輯。默認(rèn)情況下,如果沒有手動設(shè)置初始值,ThreadLocal
的初始值為 null
。
總之,initialValue()
方法用于提供一個初始值,在首次訪問 ThreadLocal
對象時使用。通過重寫該方法,我們可以自定義初始值的生成邏輯。
5. withInitial(Supplier<? extends T> supplier)
該方法用于創(chuàng)建一個具有初始值供應(yīng)者的 ThreadLocal
對象。
public static &lt;S&gt; ThreadLocal&lt;S&gt; withInitial(Supplier&lt;? extends S&gt; supplier) { return new SuppliedThreadLocal&lt;&gt;(supplier); }
解釋:該方法使用提供的 Supplier
對象來創(chuàng)建一個 SuppliedThreadLocal
對象,該對象實(shí)現(xiàn)了 ThreadLocal
接口。Supplier
是一個函數(shù)式接口,它定義了一個無參數(shù)的 get()
方法,用于獲取初始值。
通過調(diào)用 withInitial(supplier)
方法,我們可以創(chuàng)建一個具有初始值供應(yīng)者的 ThreadLocal
對象。該供應(yīng)者將在首次訪問 ThreadLocal
對象時生成初始值。
總之,withInitial(Supplier<? extends S> supplier)
方法用于創(chuàng)建一個具有初始值供應(yīng)者的 ThreadLocal
對象。通過該方法,我們可以方便地指定一個供應(yīng)者來生成初始值。
6. getMap(Thread t)
該方法用于獲取給定線程 t
對應(yīng)的 ThreadLocalMap
對象。
ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
解釋:在 ThreadLocal
類中,每個線程都有一個名為 threadLocals
的字段,它是一個 ThreadLocalMap
對象。該字段用于存儲線程本地變量的鍵值對。
在 getMap(Thread t)
方法中,通過訪問線程 t
的 threadLocals
字段,直接返回對應(yīng)的 ThreadLocalMap
對象。
這個方法的作用是為了獲取特定線程的 ThreadLocalMap
對象,以便進(jìn)行后續(xù)的操作,比如獲取或設(shè)置線程本地變量的值。
需要注意的是,getMap(Thread t)
方法是 ThreadLocal
類的內(nèi)部方法,我們通常不需要直接調(diào)用它,而是通過 ThreadLocal
對象的方法間接地訪問線程本地變量。
以上是 ThreadLocal 類常用方法的源碼和詳細(xì)解釋。這些方法允許您在多線程環(huán)境中維護(hù)線程本地變量,并提供了獲取、設(shè)置、移除 ThreadLocal 變量的功能,更多關(guān)于ThreadLocal 類常用方法源碼解析的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
String實(shí)例化及static final修飾符實(shí)現(xiàn)方法解析
這篇文章主要介紹了String實(shí)例化及static final修飾符實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09SpringMVC中@Valid不起效BindingResult讀取不到Error信息
在寫SpringMVC項(xiàng)目時,由于要對表單數(shù)據(jù)進(jìn)行校驗(yàn),需要使用@Valid進(jìn)行校驗(yàn),但是在進(jìn)行數(shù)據(jù)校驗(yàn)時,BindingResult對象無法攔截非法表單數(shù)據(jù),result.hasErrors()無論怎么輸入都會返回false,本文詳細(xì)的介紹一下解決方法2021-09-09Spring Boot 集成 RocketMQ 全流程指南(從依賴引入到消息收發(fā)
本文將通過 手動連接 和 配置連接 兩種方式,詳細(xì)講解如何在 Spring Boot 中集成 RocketMQ,實(shí)現(xiàn)消息的同步與異步發(fā)送,并提供完整示例代碼,感興趣的朋友一起看看吧2025-04-04java實(shí)現(xiàn)圖片縮放、旋轉(zhuǎn)和馬賽克化
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)圖片縮放、旋轉(zhuǎn)和馬賽克化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03SpringBoot2.4.2下使用Redis配置Lettuce的示例
這篇文章主要介紹了SpringBoot2.4.2下使用Redis配置Lettuce,Springboot2.4.2下默認(rèn)使用的就是Lettuce而不是Jedis因此無需在依賴進(jìn)行排除Jedis,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2022-01-01Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實(shí)現(xiàn)流程
這篇文章主要介紹了Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實(shí)現(xiàn)流程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07