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


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

threadLocal可以做線程級的數據隔離,那如何在子線程中獲取父線程的值呢? 可以使用InheritableThreadLocal

/**
 * Java子線程獲取父線程的threadLocal中的值
 */
public class ThreadDemo1 {

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

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

    public static void main(String[] args) throws Exception {
        inheritableThreadLocal.set("inheritableThreadLocal hello");
        threadLocal.set("threadLocal world");
        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();


        Thread.sleep(3000);
        System.out.println("--------------修改可繼承值threadLocal和threadLocal的值--------------------");
        inheritableThreadLocal.set("inheritableThreadLocal hello2");
        threadLocal.set("threadLocal world2");


        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();
    }
}

  

輸出結果如下:

子線程可繼承值:inheritableThreadLocal hello
子線程值:null
孫線程可繼承值:inheritableThreadLocal hello
孫線程值:null
--------------修改可繼承值threadLocal和threadLocal的值--------------------
子線程可繼承值:inheritableThreadLocal hello2
子線程值:null
孫線程可繼承值:inheritableThreadLocal hello2
孫線程值:null

 說明在子線程和孫線程中可以獲取到父線程的 inheritableThreadLocal 的值。修改inheritableThreadLocal 的值后,子線程和孫線程中同樣可以獲取到父線程的inheritableThreadLocal 的值。

但是threadLocal卻不行,獲取到的值為空。

 

2、查看創建Thread的源碼

 private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        ......
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

    //ThreadLocal.createInheritedMap
    static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
        return new ThreadLocalMap(parentMap);
    }

  可以看到,創建線程時,調用了init方法,然后將父線程的inheritableThreadLocals賦值inheritableThreadLocals  (ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;)

 


免責聲明!

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



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