最近微信群里一个网友分享了他京东一面的过程,我这里分享给大家其中一道面试题。
京东一面:子线程如何获取父线程 ThreadLocal 的值
子线程如何获取父线程 ThreadLocal 的值
图片
想要子线程获取父线程中 ThreadLocal 中的值,须要其子类 InheritableThreadLocal 实现。
测试代码如下:
public static void main(String[] args) throws InterruptedException {Thread parentParent = new Thread(() -> {ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(1);
InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>();
inheritableThreadLocal.set(2);
new Thread(() -> {System.out.println("threadLocal=" + threadLocal.get());
System.out.println("inheritableThreadLocal=" + inheritableThreadLocal.get());
}).start();}, "父线程");
parentParent.start();}
运行后果如下:
子线程获取父线程中 ThreadLocal 中的值。另外,上周抽时间整顿了一份简历材料,既蕴含简历撰写的要点,还收录了几位大佬的简历模板,感兴趣的小伙伴赶快来这里支付吧!
原理如下:
首先咱们要晓得 Thread 类保护了两个 ThreadLocalMap
图片
跟进 new Thread() 办法
其构造方法调用了 init 办法, init 办法把 inheritThreadLocals 值设置为了 true
图片
持续跟进。程序员专属的壁纸,关注公众号 SpringForAll 社区,回复:壁纸,即可支付高清无水印壁纸。
当 inheritThreadLocals
的值为 true 并且其父线程的 inheritableThreadLocals
不为 null 时, 把其父线程 inheritableThreadLocals
赋值给以后线程的inheritableThreadLocals
图片
这就是子线程能够获取到父线程 ThreadLocal 值的要害。举荐:上周抽时间整顿了一份简历材料,既蕴含简历撰写的要点,还收录了几位大佬的简历模板,感兴趣的小伙伴赶快来这里支付吧!
持续跟进 看看 InheritableThreadLocal
的get()办法
get()办法没什么难看的,就是 ThreadLocal 的 get()办法。
图片
留神: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
。