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

京东一面:子线程如何获取父线程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值的要害。举荐:上周抽时间整顿了一份简历材料,既蕴含简历撰写的要点,还收录了几位大佬的简历模板,感兴趣的小伙伴赶快来这里支付吧!

持续跟进 看看InheritableThreadLocalget()办法

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