子线程如何获取父线程 ThreadLocal 的值

点击下方“IT牧场”,选择“设为星标” blog.csdn.net/weixin_44912855 最近微信群里一个网友分享了他京东一面的过程,我这里分享给

点击下方“IT牧场”,选择“设为星标”

1de3751db8701b001aca363ec659951f.png

blog.csdn.net/weixin_44912855

最近微信群里一个网友分享了他京东一面的过程,我这里分享给大家其中一道面试题。

京东一面」子线程如何获取父线程ThreadLocal的值

子线程如何获取父线程ThreadLocal的值

811b0c0a409863986802493f5ebf063f.png

想要子线程获取父线程中 ThreadLocal 中的值,需要其子类 InheritableThreadLocal 实现。

测试代码如下:

public static void main(String[] args) throws InterruptedException {Thread parentParent = new Thread(() -> {ThreadLocal threadLocal = new ThreadLocal<>();threadLocal.set(1);InheritableThreadLocal inheritableThreadLocal = new InheritableThreadLocal<>();inheritableThreadLocal.set(2);new Thread(() -> {System.out.println("threadLocal=" + threadLocal.get());System.out.println("inheritableThreadLocal=" + inheritableThreadLocal.get());}).start();}, "父线程");parentParent.start();
}

运行结果如下:

597e73868a58d591c754af45b4d86bd1.png
子线程获取父线程中 ThreadLocal 中的值

原理如下:

首先我们要知道 Thread类维护了两个ThreadLocalMap

ffef78d8a142fe58324ea503f2ce2810.png

跟进 new Thread() 方法

其构造方法调用了init方法, init方法把inheritThreadLocals值设置为了true

deb957ea8e4035357194cf3f7bce6993.png

继续跟进。

当inheritThreadLocals的值为true并且其父线程的inheritableThreadLocals不为null时, 把其父线程inheritableThreadLocals 赋值给当前线程的inheritableThreadLocals

954db8ca6f7678ac16cb5ff68e22df4f.png

这就是子线程可以获取到父线程ThreadLocal值的关键。

继续跟进 看看 InheritableThreadLocal 的get() 方法

get()方法没什么好看的,就是ThreadLocal的get()方法。

c6e29aa73d39aff30a73c504d20703c0.png

注意:InheritableThreadLocal 对ThreadLocal 的getMap()方法进行重写

ThreadLocalMap getMap(Thread t) {//获取线程自己的变量threadLocals,并绑定到当前调用线程的成员变量threadLocals上return t.threadLocals; 
}void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);//创建给ThreadLocalMap的table属性赋值,并且将firstValue放在数组首位。
}

createMap方法不仅创建了threadLocals,同时也将要添加的本地变量值添加到了threadLocals中。

InheritableThreadLocal类继承了ThreadLocal类,并重写了childValue、getMap、createMap方法。

其中createMap方法在被调用的时候,创建的是inheritableThreadLocal而不是threadLocals。

同理,getMap方法在当前调用者线程调用get方法的时候返回的也不是threadLocals而是inheritableThreadLocal。

干货分享最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!
•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术群讨论
加个关注不迷路
喜欢就点个"在看"呗^_^