InheritableThreadLocal:父子线程值传递的利器
2024-02-14 15:51:20
我们知道ThreadLocal可以实现线程之间值的传递,但如果是父子线程呢?我们来看一个简单的例子:
public class ThreadLocalTest {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
threadLocal.set("主线程值");
Thread thread = new Thread(() -> {
System.out.println("子线程值:" + threadLocal.get());
});
thread.start();
}
}
输出结果:
子线程值:null
可以看到,InheritableThreadLocal是完成了父子线程值的传递,而ThreadLocal却没有。这是因为ThreadLocal的值是存储在每个线程的ThreadLocalMap中的,而ThreadLocalMap是不会被父子线程共享的。因此,如果要在父子线程之间传递值,就需要使用InheritableThreadLocal。
InheritableThreadLocal的原理是,它会在每个线程的ThreadLocalMap中存储一个InheritableThreadLocalMap,而InheritableThreadLocalMap是会随着线程的创建而被继承的。因此,当子线程从父线程中继承ThreadLocalMap时,也会继承父线程中的InheritableThreadLocalMap,从而实现父子线程之间值的传递。
InheritableThreadLocal的用法与ThreadLocal基本相同,只需要在创建InheritableThreadLocal对象时指定inheritThreadLocals参数为true即可。例如:
private static InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
然后,就可以像使用ThreadLocal一样使用InheritableThreadLocal了。
需要注意的是,InheritableThreadLocal只能传递值,不能传递引用。这意味着,如果在父线程中修改了InheritableThreadLocal的值,子线程中的值不会受到影响。
InheritableThreadLocal非常适合在父子线程之间传递值,例如在Servlet容器中传递请求和响应对象,在EJB容器中传递上下文对象,在Spring框架中传递事务对象等。