ThreadLocal的坑--ThreadLocal跨线程传递问题
1、父子线程间的传递问题
ThreadLocal的子类InheritableThreadLocal其实已经帮我们处理好了,通过这个组件可以实现父子线程之间的数据传递,在子线程中能够父线程中的ThreadLocal本地变量。
我们发现InheritableThreadLocal中createMap,以及getMap方法处理的对象不一样了,其中在ThreadLocal中处理的是threadLocals,而InheritableThreadLocal中的是inheritableThreadLocals。
代码的意思是在Thread获取先父亲线程parent(即要创建子线程的当前这个线程)。当父亲线程中对inherThreadLocals进行了赋值,就会把当前线程的本地变量(也就是父线程的inherThreadLocals)进行createInheritedMap方法操作。查看源码createInheritedMap方法,源码可知此操作就是将赋线程的threadLocalMap传递给子线程。
参考:https://www.cnblogs.com/Nonnetta/p/10175662.html
2、使用异步线程池时的传递问题
这里有两种解决方案
1、参考Hystrix中的回调方法
在SpringCloud中的分布式链路跟踪时,traceId如何在异步线程中传递traceId呢?
看源码可以知道是通过:
Sluth是通过实现HystrixConcurrencyStrategy接口来解决traceId异步传递的问题。Hystrix在实际调用时,会调用HystrixConcurrencyStrategy的wrapCallable方法。因此,通过实现这个接口,在wrapCallable中将traceId存放起来(具体参见SleuthHystrixConcurrencyStrategy)
https://blog.csdn.net/yaowwwww7071/article/details/85769505
2、线程池采用阿里的
通过inheritableThreadLocals我们可以在父线程创建子线程的时候将Local中的值传递给子线程,这个特性已经能够满足大部分的需求了,但是还有一个很严重的问题是如果是在线程复用的情况下就会出问题,比如线程池中去使用inheritableThreadLocals 进行传值,因为inheritableThreadLocals 只是会再新创建线程的时候进行传值,线程复用并不会做这个操作,那么要解决这个问题就得自己去扩展线程类,实现这个功能。
不要忘记我们是做Java的哈,开源的世界有你需要的任何东西,下面我给大家推荐一个实现好了的Java库,是阿里开源的transmittable-thread-local。
GitHub地址:https://github.com/alibaba/transmittable-thread-local
主要功能就是解决在使用线程池等会缓存线程的组件情况下,提供ThreadLocal值的传递功能,解决异步执行时上下文传递的问题。
JDK的InheritableThreadLocal类可以完成父线程到子线程的值传递。但对于使用线程池等会缓存线程的组件的情况,线程由线程池创建好,并且线程是缓存起来反复使用的;这时父子线程关系的ThreadLocal值传递已经没有意义,应用需要的实际上是把 任务提交给线程池时的ThreadLocal值传递到任务执行时。
transmittable-thread-local使用方式分为三种,修饰Runnable和Callable,修饰线程池,Java Agent来修饰JDK线程池实现类
https://www.jianshu.com/p/24a3614dde41?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
转载于:https://www.cnblogs.com/duanxz/p/5444805.html
ThreadLocal的坑--ThreadLocal跨线程传递问题相关推荐
- JAVA跨线程传递数据方式总结
实现跨线程传递数据方式: v1:子线程使用主线程的局部变量 这种当主线程和子线程不在一快儿时就不适用.可以使用JDK原生的InheritableThreadLocal. v2:InheritableT ...
- Qt的QTcpServer连接后跨线程接收数据,即跨线程传递使用QTcpSocket连接对象
Qt QTcpServer类一个类(线程)listen监听连接,另一个类(线程)收发数据. Qt规定,QTcpSocket不能作为参数传递.如果做参数传递,编译时就会报错提示. 用server端获取到 ...
- 跨线程传递栈变量带来异常指针Crash
在手Q动漫的一份古老的代码中,现网发现少数crash,错误代码示例: char str[100] = "hello";dispatch_async(dispatch_get_mai ...
- 理解Windows窗体和WPF中的跨线程调用
你曾开发过Windows窗体程序,可能会注意到有时事件处理程序将抛出InvalidOperationException异常,信息为" 跨线程调用非法:在非创建控件的线程上访问该控件" ...
- ThreadLocal父子线程传递实现方案
前言 介绍InheritableThreadLocal之前,假设对 ThreadLocal 已经有了一定的理解,比如基本概念,原理,如果没有,可以参考:ThreadLocal源码分析解密.在讲解之前我 ...
- ThreadLocal巨坑!内存泄露只是小儿科
本文将会详细总结 ThreadLocal 容易用错的三个坑: 内存泄露 线程池中线程上下文丢失 并行流中线程上下文丢失 内存泄露 由于 ThreadLocal 的 key 是弱引用,因此如果使用后不调 ...
- jmeter跨线程组传多个值_Jmeter 跨线程组传递参数 之两种方法(转)
终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为同一个线程组下的请求是同时发送的),只需要发送一次登录请求,请求B直接用登录请求的参数即可,直 ...
- Jmeter跨线程组传递参数
jmeter的线程组之间是相互独立的,各个线程组互不影响,所以线程组A中输出的参数,是无法直接在线程组B和线程组C中被调用的. 但是有时为了方便管理,我们可能是把各个接口单独存放在不同的线程组中.拿t ...
- ThreadLocal实战之数据库执行器线程同步
前言 近来,在框架中获取数据库执行器时,一直通过参数传递,颇觉繁琐,且不符合设计常理. 故而,思虑片刻,欲将其融入至笔者框架内置的"RequestAttributes"对象中. 此 ...
- Jmeter操作之跨线程组传递参数
思路:将某一线程组内的变量通过"__setProperty"函数设置成jmeter的全局变量,在另一线程组中通过"__P"函数调用即可. 1.添加-后置处理器- ...
最新文章
- ajax发不出去请求_Ajax请求发送成功但不进success的解决方法
- python的编译器有哪些-python编译器有哪些
- 【性能优化】 之 10053 事件
- mysql忘记i密码_Mysql忘记密码处理过程
- 尚学堂科技_马士兵_设计模式
- VBA 打开文件对话框
- 【人工智能】【深度学习】初学者如何选出最适合自己深度学习框架?
- 汇编语言常见错误(转载)
- 1002. 写出这个数 (20)-PAT乙级真题
- 计算机在生产作业管理,作业管理
- win7如何设置wifi热点_win7电脑本地连接连不上怎么办?详细教您如何设置本地连接...
- c语言头文件sys wait.h,错误:sys/wait.h:没有这样的文件或目录
- pdf文件如何在线转换为jpg图片 1
- 实现内容自动撑开盒子
- [kotlin]人工智能对话程序
- winserver修改计算机用户名,windows10系统更改账户名称的方法
- Java8 Lambda表达式(三)Lambda表达式与Stream API
- 法律工作者在用的小众但功能强悍的效率工具有这些
- 手机显示无法接通服务器是怎么回事,手机无法接通是什么原因及如何解决【图文】...
- 北京系列10——返程