首页 > 解决方案 > InheritableThreadLocal 如何为实例变量线程工作?

问题描述

我有以下程序

class ParentThread extends Thread{

    public ParentThread(String s) {
        super(s);
    }

    static InheritableThreadLocal tl = new InheritableThreadLocal();
    ChildThread c = new ChildThread("child");

    @Override
    public void run() {
        tl.set("pp");
        System.out.println("Thread :"+Thread.currentThread().getName()+" thread local value: "+tl.get());
        c.start();
    }
}
class ChildThread extends Thread{
    public ChildThread(String child) {
        super(child);
    }

    @Override
    public void run() {
        System.out.println("Thread :"+Thread.currentThread().getName()+" thread local value: "+ParentThread.tl.get());
    }
}
public class ThreadLocalDemo {
    public static void main(String[] args) {
        ParentThread p = new ParentThread("parent");
        p.start();
    }
}

我得到的输出为

Thread :parent thread local value: pp
Thread :child thread local value: null

我相信即使我将 ChildThread 声明为实例变量,父线程的 run 方法也负责创建子线程。那么,为什么孩子的输出为空?

当我把这个

ChildThread c = new ChildThread("child");

在 run 方法中,我确实得到了 pp。为什么会这样?

标签: javamultithreadingthread-local

解决方案


从 API 文档:

当创建子线程时,子线程接收父线程具有值的所有可继承线程局部变量的初始值。

让我们在不改变任何实现的情况下重写ParentThread得更明确。(在演示中根本没有特别的理由ParentThread- 主线程会做得很好。编辑:我应该继续这个想法。实例从主线ChildThread程继承可继承的线程局部变量,而不是实例。ParentThread

class ParentThread extends Thread{
    static InheritableThreadLocal tl;
    static {
        tl = new InheritableThreadLocal();
    }

    /* pp */ ChildThread c;

    public ParentThread(String s) {
        super(s);
        this.c = new ChildThread("child");
    }

    @Override
    public void run() {
        tl.set("pp");
        System.out.println("Thread :"+Thread.currentThread().getName()+" thread local value: "+tl.get());
        c.start();
    }
}

在那里,我们看到ChildThread之前调用了构造函数InheritableThreadLocal.set。写new ChildThread()tl.set(pp);,应该看到值。

InheritableThreadLocal是坚果。除非做一些恶意的事情,否则我会避免它。

一般来说,我强烈建议在没有必要的情况下避免子类化和ThreadLocal.


推荐阅读