InheritableThreadLocal使用与源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Pengjx2014/article/details/82635158

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
   }

猜你喜欢

转载自blog.csdn.net/Pengjx2014/article/details/82635158