最近开发的系统有一个场景在多个RPC调用链中需要传递一些公有参数过去。
这个时候首先想到的是ThreadLocal,但是有一个问题就是它不能在父子线程中传递上下文信息(ThreadLocal变量信息),这时我们考虑用InheritableThreadLocal,它可以解决父子线程中上下文的传递,但是又发现一个问题,InheritableThreadLocal在线程池复用的组件里无法复制,最后我们这个时候考虑用TransmittableThreadLocal 解决 ,TransmittableThreadLocal这个类是来自阿里的一个开源项目:https://github.com/alibaba/tr...。这个类就是为了解决例如使用线程池、Tomcat这类缓存线程组件,如ThreadPoolExecutor、tomcat线程池的时候,某一线程中的数据和ThreadLocal等在没有删除或者解绑的情况下,会被下一个Runable类或者Http请求复用。而在提交任务给线程池时,而TransmittableThreadLocal为了解决这个问在提交任务给线程池时,将ThreadLocal数据一起提交,相当于重新set一次ThreadLocal。
当然光这个还不够,我们还要把线程池增强或者使用TtlRunnable.get()的方式,看下面代码例子
package com.jd.neptune.site.util.util;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;
import com.alibaba.ttl.threadpool.TtlExecutors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestTransmittableThreadLocal {
private static TransmittableThreadLocal<String> ttl = new TransmittableThreadLocal<>();
private static ThreadLocal tl = new ThreadLocal();
private static ExecutorService executorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));
private static ExecutorService executorService2 = Executors.newFixedThreadPool(1);
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
ttl.set("#" + i);
tl.set("#" + i);
// System.out.println("main-"+ttl.get());
// executorService.execute(() -> {
// System.out.println("child-pool-ttl-" + ttl.get());
// System.out.println("child-pool-tt-" + tl.get());
// });
// executorService2.execute(TtlRunnable.get(() -> {
// System.out.println("child-pool2-ttl-" + ttl.get());
// System.out.println("child-pool2-tt-" + tl.get());
// }));
// new Thread(() -> {
// System.out.println("child-new-ttl-" + ttl.get());
// }
// ).start();
// new Thread(() -> {
// System.out.println("child-new-tl-" + tl.get());
// }
// ).start();
executorService2.execute(() -> {
System.out.println("child-pool2-ttl-" + ttl.get());
System.out.println("child-pool2-tt-" + tl.get());
});
new Thread(() -> {
System.out.println("child-new-ttl-" + ttl.get());
}).start();
}
}
}