來源:blog.csdn.net/weixin_44912855
最近微信群里一個網友分享了他京東一面的程序,我這里分享給大家其中一道面試題,
京東一面」子執行緒如何獲取父執行緒ThreadLocal的值
子執行緒如何獲取父執行緒ThreadLocal的值

想要子執行緒獲取父執行緒中 ThreadLocal 中的值,需要其子類 InheritableThreadLocal 實作,
測驗代碼如下:
public static void main(String[] args) throws InterruptedException {
Thread parentParent = new Thread(() -> {
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(1);
InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>();
inheritableThreadLocal.set(2);
new Thread(() -> {
System.out.println("threadLocal=" + threadLocal.get());
System.out.println("inheritableThreadLocal=" + inheritableThreadLocal.get());
}).start();
}, "父執行緒");
parentParent.start();
}
運行結果如下:
子執行緒獲取父執行緒中 ThreadLocal 中的值
原理如下:
首先我們要知道 Thread類維護了兩個ThreadLocalMap

跟進 new Thread() 方法
其構造方法呼叫了init方法, init方法把inheritThreadLocals值設定為了true

繼續跟進,
當inheritThreadLocals的值為true并且其父執行緒的inheritableThreadLocals不為null時, 把其父執行緒inheritableThreadLocals 賦值給當前執行緒的inheritableThreadLocals

這就是子執行緒可以獲取到父執行緒ThreadLocal值的關鍵,
繼續跟進 看看 InheritableThreadLocal 的get() 方法
get()方法沒什么好看的,就是ThreadLocal的get()方法,

注意:InheritableThreadLocal 對ThreadLocal 的getMap()方法進行重寫
ThreadLocalMap getMap(Thread t) {
//獲取執行緒自己的變數threadLocals,并系結到當前呼叫執行緒的成員變數threadLocals上
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
//創建給ThreadLocalMap的table屬性賦值,并且將firstValue放在陣列首位,
}
createMap方法不僅創建了threadLocals,同時也將要添加的本地變數值添加到了threadLocals中,
InheritableThreadLocal類繼承了ThreadLocal類,并重寫了childValue、getMap、createMap方法,
其中createMap方法在被呼叫的時候,創建的是inheritableThreadLocal而不是threadLocals,
同理,getMap方法在當前呼叫者執行緒呼叫get方法的時候回傳的也不是threadLocals而是inheritableThreadLocal,
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
2.勁爆!Java 協程要來了,,,
3.Spring Boot 2.x 教程,太全了!
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/461829.html
標籤:Java
上一篇:最新流程引擎 flowable 6.7.2 更新說明
下一篇:hashMap、ConcurrentHashMap、hashTable、TreeMap、LinkedHashMap用法區別詳解
