ThreadLocal的短板,我TTL来补

之前我已经分析了ThreadLocal、InheritableThreadLocal、FastThreadLocal。

然后有小伙伴让我再说说TransmittableThreadLocal(下边统一简称:TTL),它是阿里开源的一个工具类,解决异步执行时上下文传递的问题。

那今天就来介绍介绍 TTL,补充下 ThreadLocal 家族的短板吧。

这篇过后,ThreadLocal 就真的一网打尽了!

不过还是建议先看看前置篇(文末会放链接),不然理解起来可能有点困难。

缘由

任何一个组件的出现必有其缘由,知其缘由背景才能更深刻地理解它。

我们知道 ThreadLocal 的出现就是为了本地化线程资源,防止不必要的多线程之间的竞争。

在有些场景,当父线程 new 一个子线程的时候,希望把它的 ThreadLocal 继承给子线程。

这时候 InheritableThreadLocal 就来了,它就是为了父子线程传递本地化资源而提出的。

具体的实现是在子线程对象被 new 的时候,即 Thread.init 的时,如果查看到父线程内部有 InheritableThreadLocal 的数据。

那就在子 Thread 初始化的时,把父线程的 InheritableThreadLocal 拷贝给子线程。

 

就这样简单地把父线程的 ThreadLocal 数据传递给子线程了。

但是,这个场景只能发生在 new Thread 的时候!也就是手动创建线程之时!那就有个问题了,在平时我们使用的时候基本用的都是线程池。

那就麻了啊,线程池里面的线程都预创建好了,调用的时候就没法直接用 InheritableThreadLocal 了。

所以就产生了一个需求,如何往线程池内的线程传递 ThreadLocal?,JDK 的类库没这个功能,所以怎么搞?

只能我们自己造轮子了。

如何设计?

需求已经明确了,但是怎么实现呢?

平时我们用线程池的话,比如你要提交任务,则使用代码如下:

Runnable task = new Runnable....;
executorService.submit(task);

小贴士:以下的 ThreadLocal 泛指线程本地数据,不是指 ThreadLocal 这个类

这时候,我们想着把当前线程的 ThreadLocal 传递给线程池内部将要执行这个 task 的线程。

但此时我们哪知道线程池里面的哪个线程会来执行这个任务?

所以,我们得先把当前线程的 ThreadLocal 保存到这个 task 中。

然后当线程池里的某个线程,比如线程 A 获取这个任务要执行的时候,看看 task 里面是否有存储着的 ThreadLocal 。

如果存着那就把这个 ThreadLocal 放到线程 A 的本地变量里,这样就完成了传递。

然后还有一步,也挺关键的,就是恢复线程池内部执行线程的上下文,也就是该任务执行完毕之后,把任务带来的本地数据给删了,把线程以前的本地数据复原。

 

设计思路应该已经很明确了吧?来看看具体需要如何实现吧!

如何实现?

把上面的设计简单地、直白地翻译成代码如下

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值