TransmittableThreadLocal

月伴飞鱼 2025-01-03 22:34:10
框架相关
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

TransmittableThreadLocalInheritableThreadLocal 的增强版。

  • 主要用于解决在线程池环境中父子线程间传递上下文数据的问题。

它由阿里巴巴的开源库 transmittable-thread-local (TTL) 提供。

  • 解决了 InheritableThreadLocal 在线程池复用线程时数据无法自动传递的问题。

InheritableThreadLocal 可以在父线程和直接创建的子线程间传递数据。

但在线程池场景中,由于线程是被复用的,InheritableThreadLocal 无法正确地将父线程的上下文传递给子线程。

TransmittableThreadLocal 通过增强线程池的执行机制。

  • 能够在任务提交时捕获父线程的上下文,并在任务执行时将该上下文传递给子线程,确保上下文的正确传递。

使用示例

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
    <version>2.12.4</version> <!-- 请使用最新版本 -->
</dependency>

假设我们有一个需要传递上下文信息的场景,在主线程中设置一个值,并希望在线程池中执行任务时能够获取到该值:

public class TransmittableThreadLocalExample {

    // 创建 TransmittableThreadLocal 变量
    private static final TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();

    public static void main(String[] args) {

        // 设置主线程的上下文值
        transmittableThreadLocal.set("Parent Thread Value");

        // 创建一个线程池,并包装为 TTL 线程池
        ExecutorService executorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(2));

        // 提交任务
        executorService.submit(() -> {
            // 子线程中获取 TransmittableThreadLocal 的值
            System.out.println("Task 1: " + transmittableThreadLocal.get()); // 输出: Task 1: Parent Thread Value
        });

        // 修改父线程中的值,提交另一个任务
        transmittableThreadLocal.set("Updated Parent Thread Value");

        executorService.submit(() -> {
            // 子线程获取更新后的值
            System.out.println("Task 2: " + transmittableThreadLocal.get()); // 输出: Task 2: Updated Parent Thread Value
        });

        // 关闭线程池
        executorService.shutdown();
    }
}
Task 1: Parent Thread Value
Task 2: Updated Parent Thread Value

在这个例子中,TransmittableThreadLocal 能够将父线程的上下文信息传递到线程池中复用的子线程中。

  • 实现了线程池环境下的上下文传递。

工作机制

捕获上下文

  • 在提交任务时,TransmittableThreadLocal 捕获父线程的上下文数据,并将其附加到任务中。

传递上下文

  • 在线程池中执行任务时,TransmittableThreadLocal 将捕获的上下文设置到当前线程,以便子线程能够访问。

清理上下文

  • 任务执行完毕后,TransmittableThreadLocal 会清理线程中的上下文,避免对后续任务产生影响。

使用场景

TransmittableThreadLocal 常用于以下场景:

分布式追踪

  • 传递追踪 ID、事务 ID 等上下文信息。

日志上下文传递

  • 在不同的子线程中传递用户会话信息、请求 ID,用于生成有上下文的日志。

线程池异步任务

  • 在多线程异步任务中传递父线程的上下文参数(如用户信息、地域信息等)。

注意事项

依赖 TTL 线程池包装

  • 在线程池中使用 TransmittableThreadLocal 时。
  • 需要将线程池通过 TtlExecutors.getTtlExecutorService 进行包装,否则上下文传递将无法生效。

性能开销

  • 由于上下文的捕获、传递和清理机制。
  • TransmittableThreadLocal 相比普通的 ThreadLocalInheritableThreadLocal 会有一定的性能开销。
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!