⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/weixin_44912855 「_Louie」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

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

京东一面」子线程如何获取父线程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. 子线程如何获取父线程ThreadLocal的值