多线程与并发

业务场景实战(七)阿里TTL线程池

2022-02-12  本文已影响0人  后来丶_a24d

思维导图

思维导图.png

系列总目录


背景

在使用线程池等会池化复用线程的执行组件情况下,transmittable-thread-local(简称TTL)提供ThreadLocal值的传递功能,解决异步执行时上下文传递的问题。TTL主要解决了:

  1. 透传上下文信息,run方法调用结束时自动restore上下文信息
  2. 线程池使用CallerRunsPolicy时,避免了手动回收上下文信息会将主线程的上下文信息清空

使用

    // 使用TransmittableThreadLocal
    static TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();


    public static void main(String[] args) throws InterruptedException {

        ExecutorService executorService = Executors.newFixedThreadPool(1);
        // 用TtlExecutors装饰线程池
        executorService = TtlExecutors.getTtlExecutorService(executorService); 

        transmittableThreadLocal.set("i am a transmittable parent");
        executorService.execute((Runnable) () -> {

            System.out.println(transmittableThreadLocal.get());
            // 子线程设置新的值
            transmittableThreadLocal.set("i am a old transmittable parent");

        });
        System.out.println(transmittableThreadLocal.get());

        TimeUnit.SECONDS.sleep(1);
        // 主线程设置新的值
        transmittableThreadLocal.set("i am a new transmittable parent");
        executorService.execute((Runnable) () -> System.out.println(transmittableThreadLocal.get()));
    }


    i am a transmittable parent 
    i am a transmittable parent
    i am a new transmittable parent

源码

  1. 线程池执行时,执行了 ExecutorTtlWrapper execute 方法,execute 方法中调用了 4.1.1,4.1.1 方法中创建了一个 TtlRunnable 对象返回了。
    TtlRunnable 构造方法中,调用了 TransmittableThreadLocal.Transmitter.capture() 获取当前线程中所有的上下文,并储存在 AtomicReference 中。
  2. 当线程执行时,调用 TtlRunnable run 方法,TtlRunnable 会从 AtomicReference 中获取出调用线程中所有的上下文,并把上下文给 TransmittableThreadLocal.Transmitter.replay 方法把上下文复制到当前线程。并把上下文备份。
  3. 当线程执行完,调用 TransmittableThreadLocal.Transmitter.restore 并把备份的上下文传入,恢复备份的上下文,把后面新增的上下文删除,并重新把上下文复制到当前线程。

参考文章

上一篇 下一篇

猜你喜欢

热点阅读