ThreadLocal源碼——JDK中如何實現(xiàn)為每一個使用該變量的線程都提供一個變量值的副本

說好的技術(shù)博客,現(xiàn)在就來第一篇

最近一段時間在把一個本地工具搭成web版本,進行一些封裝,針對一些業(yè)務(wù)功能還要進行在開發(fā)。用到一些并發(fā)模型,涉及一點線程。陸陸續(xù)續(xù)會更新編寫過程中遇到、用到、學(xué)到的東西。

這篇主要說一下ThreadLocal。

網(wǎng)上有很多ThreadLocal的使用教程,也都提到ThreadLocal為每個使用該變量的線程提供獨立的變量副本,而不會影響到其他線程。講到實現(xiàn)原理的時候,都提到說:
JDK中ThreadLocal類中有一個Map,key是線程對象,valute為對應(yīng)線程的變量副本。

我想說,這是完全錯誤的。。。
其實,從JDK1.2版本開始,ThreadLocal的實現(xiàn)原理就不是這樣的。
真實的情況是,每一個Thread內(nèi),都會有一個ThreadLocalMap用來存放自己用到的ThreadLocal,key為ThreadLocal實例,value為使用時set進去的對象。

我們從源碼的角度來分析(使用jdk1.7版本)
首先來看ThreadLocal的set方法

java.lang.ThreadLocal public void set(T value) { Thread t = Thread.currentThread();//取到當前線程,native方法 ThreadLocalMap map = getMap(t);//我想誤解應(yīng)該是從這句開始的,后面會詳細說 if (map != null) map.set(this, value);//key為ThreadLocal,value為set進來的對象 else createMap(t, value); }
乍一看是通過當前線程t取到了ThreadLocalMap,其實是從t中取到ThreadLocalMap對象,我們看一眼getMap(t)方法的實現(xiàn)就清楚了。

java.lang.ThreadLocal ThreadLocalMap getMap(Thread t) { return t.threadLocals; }

java.lang.Thread ThreadLocal.ThreadLocalMap threadLocals = null;

這就是ThreadLocal為什么會是每個線程單獨擁有的。
在每個Thread中會有一個ThreadLocalMap,當我們調(diào)用某一個ThreaLocal實例的set方法時,會去當前Thread中取ThreadLocalMap,使用ThreadLocal實例為key,將set進來的值作為value存儲在map中。

The end

另附createMap方法

java.lang.ThreadLocal void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }

PS:ThreadLocalMap也挺有意思,他是一個被標示為static的內(nèi)部類,核心是Entry[],Entry也為static,繼承自WeakReference<ThreadLocal>。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容