跨线程传递ThreadLocal

  • ThreadLocal的值存放在Thread中,父子线程属于不同的Thread,因此子线程无法访问父线程的ThreadLocal值。

  • 如果需要在子线程中访问父线程的ThreadLocal值,有两种方法:

    • 使用InheritableThreadLocal类,它是ThreadLocal的子类。使用它时,在创建子线程时,子线程会自动继承父线程的ThreadLocal值。但是无法支持线程池场景下的ThreadLocal传递。
    • 使用TransmittableThreadLocal类,它是阿里巴巴开源的一个类,继承并加强了InheritableThreadLocal,支持线程池场景下的ThreadLocal传递。需要引入transmittable-thread-local依赖。项目地址:https://github.com/alibaba/transmittable-thread-local
  • InheritableThreadLocal原理:创建子线程时拿到父线程的inheritableThreadLocals变量赋值给子线程即可:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Thread 的构造方法会调用 init() 方法
    private void init(/* ... */) {
    // 1、获取父线程
    Thread parent = currentThread();
    // 2、将父线程的 inheritableThreadLocals 赋值给子线程
    if (inheritThreadLocals && parent.inheritableThreadLocals != null)
    this.inheritableThreadLocals =
    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    }