京东一面:子线程如何获取父线程 ThreadLocal 的值?我蒙了。。。

简介: 京东一面:子线程如何获取父线程 ThreadLocal 的值?我蒙了。。。

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

image.png

想要子线程获取父线程中 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();
}


运行结果如下:

image.png

子线程获取父线程中 ThreadLocal 中的值


原理如下:

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

image.png


跟进 new Thread() 方法

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


image.png


继续跟进。

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


image.png

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


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


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


image.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。


相关文章
|
5月前
|
存储 监控 安全
解锁ThreadLocal的问题集:如何规避多线程中的坑
解锁ThreadLocal的问题集:如何规避多线程中的坑
190 0
|
5月前
|
存储 Java 测试技术
ThreadLocal:线程专属的变量
ThreadLocal:线程专属的变量
60 0
|
3月前
|
存储 SQL Java
(七)全面剖析Java并发编程之线程变量副本ThreadLocal原理分析
在之前的文章:彻底理解Java并发编程之Synchronized关键字实现原理剖析中我们曾初次谈到线程安全问题引发的"三要素":多线程、共享资源/临界资源、非原子性操作,简而言之:在同一时刻,多条线程同时对临界资源进行非原子性操作则有可能产生线程安全问题。
|
3月前
|
安全 Java
多线程线程安全问题之避免ThreadLocal的内存泄漏,如何解决
多线程线程安全问题之避免ThreadLocal的内存泄漏,如何解决
|
3月前
|
存储 安全 Java
多线程线程安全问题之ThreadLocal是什么,它通常用于什么场景
多线程线程安全问题之ThreadLocal是什么,它通常用于什么场景
|
3月前
|
存储 缓存 Java
Java面试题:解释Java中的内存屏障的作用,解释Java中的线程局部变量(ThreadLocal)的作用和使用场景,解释Java中的锁优化,并讨论乐观锁和悲观锁的区别
Java面试题:解释Java中的内存屏障的作用,解释Java中的线程局部变量(ThreadLocal)的作用和使用场景,解释Java中的锁优化,并讨论乐观锁和悲观锁的区别
40 0
|
3月前
|
并行计算 算法 安全
Java面试题:解释Java内存模型的内存屏障,并讨论其对多线程并发的影响,解释Java中的线程局部变量(ThreadLocal)的工作原理,解释Java中的ForkJoinPool的工作原理
Java面试题:解释Java内存模型的内存屏障,并讨论其对多线程并发的影响,解释Java中的线程局部变量(ThreadLocal)的工作原理,解释Java中的ForkJoinPool的工作原理
31 0
|
5月前
|
存储 安全 Java
调用链跨线程传递 ThreadLocal 对象对比
说起本地线程专属变量,大家首先会想到的是 JDK 默认提供的 ThreadLocal,用来存储在整个链路中都需要访问的数据,并且是线程安全的。由于在落地全链路压测的过程中,一个基本并核心的功能需求是流量标记需要在整个链路中进行传递,那么线程上下文环境成为解决这个问题最合适的技术。
71 2
调用链跨线程传递 ThreadLocal 对象对比
|
5月前
|
安全 Java
java中线程经常被问到ThreadLocal你懂吗?
java中线程经常被问到ThreadLocal你懂吗?
27 0
|
5月前
|
Java 关系型数据库 MySQL
【数据库连接,线程,ThreadLocal三者之间的关系】
【数据库连接,线程,ThreadLocal三者之间的关系】
57 0