Alibaba TTL跨线程参数传递框架

目录

1.功能

2.使用方式

3.扩展


1.功能

引用github的描述,https://github.com/alibaba/transmittable-thread-local

在使用线程池等会池化复用线程的执行组件情况下,提供ThreadLocal值的传递功能,解决异步执行时上下文传递的问题。

JDK的InheritableThreadLocal类可以完成父线程到子线程的值传递。但对于使用线程池等会池化复用线程的执行组件的情况,线程由线程池创建好,并且线程是池化起来反复使用的;这时父子线程关系的ThreadLocal值传递已经没有意义,应用需要的实际上是把 任务提交给线程池时的ThreadLocal值传递到 任务执行时。 

2.使用方式

TTL框架提供了两种实现跨线程参数传递的方式:

2.1. 项目代码干预的方式

代码干预主要是用TTL的装饰类装饰项目中使用的线程池,框架中的工具类为:TtlExecutors

涉及装饰的JDK组件有:Executor、ExecutorService、ScheduledExecutorService,分别对应点装饰类为:ExecutorTtlWrapper、ExecutorServiceTtlWrapper、ScheduledExecutorServiceTtlWrapper

这里装饰的目的是对线程池中方法参数为Runnable或Callable的参数,装换为对应的装饰类:TtlRunnable、TtlCallable,

TtlRunnable的run方法的方法其中,就在运行时,将任务执行主线程的ThreadLocal值传递到了线程池中池化的线程中;

**
     * wrap method {@link Runnable#run()}.
     */
    @Override
    public void run() {
        Object captured = capturedRef.get();
        if (captured == null || releaseTtlValueReferenceAfterRun && !capturedRef.compareAndSet(captured, null)) {
            throw new IllegalStateException("TTL value reference is released after run!");
        }

        Object backup = replay(captured);
        try {
            runnable.run();
        } finally {
            restore(backup);
        }
    }

这里replay方法完成父线程到子线程的值传递,同时保留了子线程的上下文信息,任务执行完成,restore方法起到恢复现场的作用;

2.2. agent挂载的方式

agent的方式本质上是字节码织入的方式,改造线程池的字节码,完成织入逻辑,对项目代码无侵入性,对应的agent实现类为:TtlAgent

3.扩展

公司的组件Mtrace跨线程传递trace信息时就是参考了TTL框架,提供了手工装饰的方式以及Agent挂载的方式;

agent包:

Alibaba TTL跨线程参数传递框架_第1张图片

 api包:

Alibaba TTL跨线程参数传递框架_第2张图片

你可能感兴趣的:(spring,异步,multi-thread,java,后端,spring)