京東一面:子線程如何獲取父線程 ThreadLocal 的值?我蒙了。。。

來源: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開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章