1. 程式人生 > >InheritableThreadLocal使用與原始碼分析

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
   }