TransmittableThreadLocal简述和使用demo

概述

业务中经常会遇到多线程之间的上下文传递,比如自己开启子线程异步执行,或者使用线程池异步执行时,需要把token/request上下文传递.

手写的话,在创建子线程时需要自己包裹一下;
在使用线程池时需要对execute方法进行包裹,比如springThreadPoolTaskExecutor中的TaskDecorator.

com.alibaba.ttl.TransmittableThreadLocal就帮我们做好了这个包裹过程,称为装饰更合适一点。
需要引入maven依赖;我当前用的是2.14.2的版本

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>transmittable-thread-localartifactId>
    <version>2.14.2version>
dependency>

TransmittableThreadLocal

java.lang.InheritableThreadLocal的子类,对线程变量copy的时机做了调整,

java.lang.InheritableThreadLocal是在new的时候将调用线程的threadLocals线程内容copyinheritableThreadLocals中.

TransmittableThreadLocal则是在run的时候才去copy调用线程的内容(copy的时候会返回调用线程的信息),并且会在调用结束后,将调用线程的内容重新塞回去

为什么要再塞回去,我想的是考虑了调用线程池时,策略为java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy#CallerRunsPolicy时,线程池满了交由调用线程执行时,此时线程执行内容中修改了threadLocals后对调用线程造成干扰。

使用demo

//只需要包裹一下即可
com.alibaba.ttl.TtlRunnable.get(java.lang.Runnable, boolean)
ttlRunnable.run();


//也可以包裹线程池Executors,其实内部在execute时也还是用的 TtlRunnable.get
ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));

你可能感兴趣的:(JAVA,springboot,多线程,java,spring)