起源:blog.csdn.net/weixin_44912855
最近微信群里一个网友分享了他京东一面的过程,我这里分享给大家其中一道面试题。
京东一面」子线程如何获取父线程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
持续跟进。
当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。
近期热文举荐:
1.1,000+ 道 Java面试题及答案整顿(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞+转发哦!