不卖关子,用InheritableThreadLocal。
关于ThreadLocal可以参考我的另一篇文章
ThreadLocal使用及原理_编程还未的博客-优快云博客
ThreadLocal实战源码在文末。
1.使用
直接上代码。
public class InheritableThreadLocalTest1 {
public static void main(String[] args) {
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(1);
InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>();
inheritableThreadLocal.set(2);
new Thread(() -> {
System.out.println("threadLocal=" + threadLocal.get());
//debug到这一行看源码
System.out.println("inheritableThreadLocal=" + inheritableThreadLocal.get());
}).start();
}
}
运行结果
threadLocal=null
inheritableThreadLocal=2
2.原理
Thread类里面有两个ThreadLocal对象,一个是threadLocals(ThreadLocal对象),一个是inheritableThreadLocals(InheritableThreadLocal对象)。
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
默认的new Thread()会获取parent线程的inheritableThreadLocals,并赋值。
public Thread(Runnable target) {
this(null, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
this(group, target, name, stackSize, null, true);
}
/**
*精简后的代码
*/
private Thread(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
Thread parent = currentThread();
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
InheritableThreadLocal本身也比较简单。主要是getMap()、createMap()
的时候操作的是Thread的inheritableThreadLocals
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
public InheritableThreadLocal() {}
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);
}
}
3.实战源码
具体的介绍,已经在我的博文,ThreadLocal使用及原理_编程还未的博客-优快云博客,介绍过了。
ThreadLocal实战,源码地址:highway-resources: threadlocal-current-user
关注公众号- 编程highway - 获取更多好文和学习资料