南宁Java设计培训机构哪一家实力强值得推荐,南宁Java设计培训机构-达内,达内java java培训,美国上市公司,亿元级Java培训学院,专注Java培训19年,历经19年,校区遍布70座城市,23万合作企业,学完达内推荐就业!
下文是南宁Java设计培训机构小编分享“线程池如何传递ThreadLocal”,一起看看吧
在做分布式链路追踪系统的时候,需要解决异步调用透传上下文的需求,特别是传递traceId,本文就线程池透传几种方式进行分析。
其他典型场景例子:
分布式跟踪系统或全链路压测(即链路打标)
日志收集记录系统上下文
Session级Cache应用容器或上层框架跨应用代码给下层SDK传递信息
1、JDK对跨线程传递ThreadLocal的支持
首先看一个较简单场景,也是一个错误的例子。
void testThreadLocal(){
ThreadLocal Object threadLocal=new ThreadLocal();
threadLocal.set("not ok");
new Thread(()->{
System.out.println(threadLocal.get());
}).start();
}
java中的threadlocal,是绑定在线程上的。你在一个线程中set的值,在另外一个线程是拿不到的。
上面的输出是:
null1.1 InheritableThreadLocal例子
JDK考虑了这种场景,实现了InheritableThreadLocal,不要高兴太早,这个只是支持父子线程,线程池会有问题。
我们看下InheritableThreadLocal的例子:
InheritableThreadLocal itl=new InheritableThreadLocal<>();
itl.set("father");
new Thread(()->{
System.out.println("subThread:"+itl.get());
itl.set("son");
System.out.println(itl.get());
}).start();
Thread.sleep(500);//等待子线程执行完
System.out.println("thread:"+itl.get());
上面的输出是:
subThread:father//子线程可以拿到父线程的变量
sonthread:father//子线程修改不影响父线程的变量
1.2 InheritableThreadLocal的实现原理
有同学可能想知道InheritableThreadLocal的实现原理,其实特别简单。就是Thread类里面分开记录了ThreadLocal、InheritableThreadLocal的ThreadLocalMap,初始化的时候,会拿到parent.InheritableThreadLocal。直接上代码可以看的很清楚。