java子線程中獲取父線程的threadLocal中的值


我們都知道線程本地變量表也就是ThreadLocal在我們做線程級的數據隔離時非常好用,但是有時候我們會想如何讓子線程獲取到父線程的ThreadLocal,其實在線程中除了ThreadLocal外還有InheritableThreadLocal,顧名思義,可繼承的線程變量表,可以讓子線程獲取到父線程中ThreadLocal的值。

public class BaseTest {

    public static  final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
    public static final ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        inheritableThreadLocal.set("Inheritable hello");
        threadLocal.set("hello");
        new Thread(()->{
            System.out.println(String.format("子線程可繼承值:%s",inheritableThreadLocal.get()));
            System.out.println(String.format("子線程值:%s",threadLocal.get()));
            new Thread(()->{
                System.out.println(String.format("孫子線程可繼承值:%s",inheritableThreadLocal.get()));
                System.out.println(String.format("孫子線程值:%s",threadLocal.get()));
            }).start();

        }).start();


    }

執行后獲取返回值。

 

 可以看到不可繼承的ThreadLocal子線程是不能共享父線程的。可繼承的ThreadLocal如何實現呢? 

其原理和ThreadLocal基本上一致,都是線程中存有ThreadLocalMap

/* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

 我們在new線程時init方法會有如下操作。

Thread parent = currentThread();      
../省略代碼
if (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);

如果允許new的線程繼承當前線程的threadlocalMap,那么new的線程會copy一份當前線程也就是父線程的inheritableThreadLocals 。這兒也可以說明繼承有兩條件,new的線程允許繼承(默認允許),父線程的inheritableThreadLocals 不為null。

 

**這兒要注意不管是創建ThreadLocal還是inheritableThreadLocals(如果父線程沒有) 的ThreadLocalMap都是在Threadlocal.set方法的時候創建的,即懶加載。

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM