InheritableThreadLocal使用與源碼分析

InheritableThreadLocal使用

 子線程需要獲取父線程中的ThreadLocal中的值的時候,使用InheritableThreadLocal

public class TestInheritableThreadLocal {

    public static final SecureRandom random = new SecureRandom();
    public static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        threadLocal.set(random.nextInt());
        GetValThread thread = new GetValThread();
        thread.start();
        System.out.println("main----" + threadLocal.get());
    }

    static class GetValThread extends Thread {
        @Override
        public void run() {
            System.out.println("local thread ----" + threadLocal.get());
        }
    }
}

運行結果如下:

main-----1845871892
local thread ----null

代碼

 public static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

修改爲:

 public static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();

運行結果如下:

main-----610914016
local thread -----610914016

InheritableThreadLocal源碼分析

InheritableThreadLocal源碼很簡單,重寫了ThreadLocal中“

public class InheritableThreadLocal<T> extends ThreadLocal<T> {

    protected T childValue(T parentValue) {
        return parentValue;
    }

    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}

InheritableThreadLocal獲取值的過程如下,從自己的ThreadLocalMap中取值。

 public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

InheritableThreadLocal本身的ThreadLocalMap初始化在創建線程自己的時候,copy父線程的ThreadLocalMap,具體實現在Thread構造函數中,具體如下:

private void init(ThreadGroup g, Runnable target, String name,
                     long stackSize, AccessControlContext acc) {
       //省略上面部分代碼
       if (parent.inheritableThreadLocals != null)
       //這句話的意思大致不就是,copy父線程parent的map,
       //創建一個新的map賦值給當前線程的inheritableThreadLocals。
           this.inheritableThreadLocals =
               ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
      //ignore
   }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章