返回

InheritableThreadLocal:父子线程值传递的利器

后端

我们知道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框架中传递事务对象等。