之前面试的时候,当谈到ThreadLocal时,被人问到,在子线程中如何获取父线程的ThreadLocal里面存储的变量。今天看到了一个类InheritableThreadLocal才明白原来是这样来做的。
先来看一下InheritableThreadLocal的源码。
public class InheritableThreadLocal<T> extends ThreadLocal<T> {/*** Computes the child's initial value for this inheritable thread-local* variable as a function of the parent's value at the time the child* thread is created. This method is called from within the parent* thread before the child is started.* <p>* This method merely returns its input argument, and should be overridden* if a different behavior is desired.** @param parentValue the parent thread's value* @return the child thread's initial value*/protected T childValue(T parentValue) {return parentValue;}/*** Get the map associated with a ThreadLocal.** @param t the current thread*/ThreadLocalMap getMap(Thread t) {return t.inheritableThreadLocals;}/*** Create the map associated with a ThreadLocal.** @param t the current thread* @param firstValue value for the initial entry of the table.*/void createMap(Thread t, T firstValue) {t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);}
}
可以看到,它继承自ThreadLocal,既然有了ThreadLocal,为什么还要弄这么个类出来呢,原因就是通过这个类可以帮我们在子线程中获取到父线程的ThreadLocal变量。
下面来演示对比一下。
public class TestThreadLocal {private static ThreadLocal T = new ThreadLocal();public static void main(String[] args) {T.set("23abc");System.out.println("main" + T.get());new Thread(() -> System.out.println("sub" + T.get())).start();}
}
输出
main23abc
subnull
然后我们将ThreadLocal换成InheritableThreadLocal
然后再次输出
main23abc
sub23abc
可以看到,子线程已经拿到了父线程的ThreadLocal里面的值了。