ThreadLocal在上下文的数据传输上非常的方便和简洁。 工业实践中,比较常用的有三个,ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal,那么他们三个之间有什么区别呢? 常见的三种ThreadLoc
ThreadLocal在上下文的数据传输上非常的方便和简洁。 工业实践中,比较常用的有三个,ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal,那么他们三个之间有什么区别呢? 常见的三种ThreadLocal比较
针对线程池的数据传输,InheritableThreadLocal仅仅能在一些简单场景下做到,下面就用一个案例来说明
?
?
从运行结果来看,前面的两次循环提交的任务,在子线程中确实是能正常的获取主线程设置的变量,即hello main,但是紧接着,我修改了主线程上绑定的变量为hello world,然后继续循环两次提交两个任务,这个时候子线程中获取的线程变量依然是hello main,这明显是与是期望不一致的。 从这个层面来讲,InheritableThreadLocal确实在线程池的层面支持不够友好,可以说仅支持部分简单场景。 根本原因就死线程池的池化机制,从上面的运行日志上也可以看出,提交了4个任务执行的线程依然是两个。线程池中的线程是复用的,InheritableThreadLocal是在创建子线程的时候,会将主线程上绑定的数据拷贝过来,如果我不创建新的线程,但是主线程上绑定的数据改变了呢?那我依然还是读取到之前拷贝的数据。 这个就是InheritableThreadLocal的短板。针对这个问题,阿里开源的TransmittableThreadLocal就能顺利丝滑的解决这个问题。 TransmittableThreadLocal实践maven依赖?
装饰Runnable任务
?
与第一个案例的差异点在于,使用了 ?
来增强了了Runnable任务,执行的结果也是符合预期。 装饰线程池
?
与上一个案例的差异点在于,这里没有包装Runnable任务,而是包装了线程池,使用了 ?
包装了ExecutorService,执行结果也是符合预期 使用java Agent无侵入增强线程池
?
项目运行的时候,需要添加额外的jvm启动参数,如下
总结阿里巴巴的TransmittableThreadLocal是继承自InheritableThreadLocal,对他的功能进行了增强,增强的点也主要是在线程池的支持上。 通过上面的三个案例,可以看到TransmittableThreadLocal是非常灵活的,大家可以根据自己的需要,选择对应的方式来实现。 |
2021-06-05
2021-05-27
2021-05-26
2021-06-05
2021-05-16