java子线程中获取父线程的threadLocal中的值

复制代码
 1 package com.example.springbootstudy.test.threadLocal;
 2 
 3 public class BaseTest {
 4 
 5     public static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
 6 
 7     public static final ThreadLocal<String> threadLocal = new ThreadLocal<>();
 8 
 9     public static void main(String[] args) {
10         inheritableThreadLocal.set("Inheritable hello");
11         threadLocal.set("hello");
12 
13         new Thread(() -> {
14             System.out.println(String.format("子线程可继承值:%s", inheritableThreadLocal.get()));
15             System.out.println(String.format("子线程值:%s", threadLocal.get()));
16 
17             new Thread(() -> {
18                 System.out.println(String.format("孙子线程可继承值:%s", inheritableThreadLocal.get()));
19                 System.out.println(String.format("孙子线程值:%s", threadLocal.get()));
20             }).start();
21         }).start();
22 
23         System.out.println(String.format("主线程-inheritableThreadLocal:%s", inheritableThreadLocal.get()));
24         System.out.println(String.format("主线程-threadLocal:%s", threadLocal.get()));
25     }
26 
27 }
复制代码

运行结果如下所示:

子线程可继承值:Inheritable hello
主线程-inheritableThreadLocal:Inheritable hello
子线程值:null
主线程-threadLocal:hello
孙子线程可继承值:Inheritable hello
孙子线程值:null

InheritableThreadLocal 是如何做到的呢?
我们先看下类结构

复制代码
public class Thread{
     ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
}

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }
    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}
    
复制代码

这里重写了ThreadLocal的操作ThreadLocalMap的方法,其实就是把从Thread类操作threadLocals变量,切换到inheritableThreadLocals变量上。
这不就是跟ThreadLocal一样吗?只是换了个变量名! 但是实际上Thread类初始化时还有一些骚操作,请看:

复制代码
 1 public class Thread{
 2     public Thread(){
 3         if (inheritThreadLocals && parent.inheritableThreadLocals != null)
 4             this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
 5     }
 6 }
 7 
 8 //ThreadLocal 类里的方法
 9    static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
10         return new ThreadLocalMap(parentMap);
11     }
复制代码

这里判断父线程的inheritableThreadLocals有值, 就拷贝到当前子线程的inheritableThreadLocals , 这样我们就能在子线程获取到父线程的值了。
这里要注意的是,并不是复制的指针,而是复制了副本。你在子线程重新set值后, 并不会影响父线程的值。

posted @   郭慕荣  阅读(260)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-06-03 rocketMQ的消息堆积如何处理
2021-06-03 RocketMQ Rebalance流程分析
2021-06-03 RocketMQ之Namesrv
点击右上角即可分享
微信分享提示