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值后, 并不会影响父线程的值。
郭慕荣博客园
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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