目录
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.扩展
公司的Trace组件跨线程传递trace信息时就是参考了TTL框架,提供了手工装饰的方式以及Agent挂载的方式;
agent包:
api包: