前言
最近优化公司项目一个功能,由于牵涉到数据量比较大,业务复杂,之前单线程执行响应时间比较久,大概10s左右。优化的思路,想到了多线程执行。
由于业务中使用了ThreadLocal,它是来解决变量在多线程使用相互影响问题,ThreadLocal能够做到变量在多线程间隔离,是因为每个线程将变量存储到自己的threadLocals(ThreadLocal.ThreadLocalMap类型)中。如果使用多线程话,需要解决父子线程值传递问题,想到了InheritableThreadLocal,它是将变量存储在inheritableThreadLocals,在创建子线程时,会将父线程值传递到子线程。似乎使用InheritableThreadLocal问题不大,在本地调试过程也不会有什么问题,测试环境执行会出现部分线程 InheritableThreadLocal 拿不到值问题,这是因为忘记了环境因素,现在项目不可能显示穿件线程,基本都有自己的线程池。InheritableThreadLocal 在set值时,线程池中部分线程是已经存活着的,所有这部分线程inheritableThreadLocals变量中是不可能有父线程传递过来的值,因为压根不存在创建过程。
由于线程池的问题,想到了阿里开源的TransmittableThreadLocal 简称ttl。
过程
先看下我自己创建的测试类
public class TransmittableThreadLocalTest {
private static ExecutorService executorService = Executors.newFixedThreadPool(1);
private static ThreadLocal<Map<String,String>> threadLocal=new TransmittableThreadLocal<Map<String,String>>();
public static void main(String[] args) {
Map<String, String> map = threadLocal.get();
if (map == null) {
threadLocal.set(new HashMap<>());
}
threadLocal.get().put("test", "test");
executorService.submit(TtlRunnable.get(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
}
System.out.println("子线程获取的值:" + threadLocal.get());
}
}));
threadLocal.get().put("second", "second");
Map mainValue = threadLocal.get();
System.out.println("主线程获取的值&#