TransmittableThreadLocal 解决线程本地变量在线程池之间的传递问题

上一个博客中提到的 InheritableThreadLocal在线程池的应用中会产生问题.

博客地址:https://blog.csdn.net/hewenbo111/article/details/80487252

因为线程池中的线程是会被复用的,所以在使用线程池进行多线程编程时,如需操作本地变量则需要特别注意!

本次博客会演示使用 TransmittableThreadLocal 解决线程本地变量在线程池之间的传递问题。

 

问题复现:

创建一个线程池并设置默认的大小为2,并在主线程中多次对线程本地变量赋值,每次赋值完以后线程池获取,如下:

               

运行结果: 主线程中对于本地变量的修改并没有完全引起线程池中的线程本地变量的修改。

                

 

问题分析:

InheritableThreadLocal可以实现线程本地变量在父子线程之间的传递,而线程池中的线程是复用的,所以要想分析出为什么能得到如上的执行结果,我们需要弄清楚线程池中的线程何时被创建。前面博客对线程池的源代码有过简单的剖析,这里只说结论。

线程池在使用的时候,例如上述代码中的submit操作,如果线程池内线程的数量小于开始设定的线程数量,则会把当前的任务作为第一个任务并创建新的线程去执行。所以上述代码中前两次使用线程池submit task的时候,变量分别传递成功。因为线程池的线程是主线程创建的子线程。而在submit task的时候,如果线程池中线程数量已经达到设定值,则不会创建线程,而是复用线程池中的线程,所以线程池中线程的本地变量也是复用的创建时设置的变量。因而出现后两次变量传递不成功的现象。

 

解决方案:

引入阿里提供的技术:TransmittableThreadLocal

github地址:https://github.com/alibaba/transmittable-thread-local

使用步骤:

       ①:引入依赖包到pom文件中          

       <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>transmittable-thread-local</artifactId>
          <version>2.2.0</version>
       </dependency>

       ②:修改代码使用新的线程本地变量

              

 

      ③: 根据官方给定的方式进行修饰,保证值的正确传递

               3.1  修饰RunnableCallable

               3.2  TtlExecutors 修饰线程池

     3.3  使用Java Agent来修饰JDK线程池实现类

               本人使用的是方法2,直接对线程池进行修饰,便于集中管理. 详情可参考github文档描述.

        

          

 

    ④:运行结果

          

具体的实现原理后续再阅读并整理,文章多有不足,欢迎大家指正,讨论。万分感谢!!!

 

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值