有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java对于实例变量线程,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声明为实例变量,父线程运行方法仍负责创建子线程。那么,为什么子级的输出为空呢

当我把这个

ChildThread c = new ChildThread("child");

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


共 (1) 个答案

  1. # 1 楼答案

    从API文档中:

    when a child thread is created, the child receives initial values for all inheritable thread-local variables for which the parent has values.

    让我们重写ParentThread,使其更加明确,而不改变任何实现。(没有特别的理由在演示中使用ParentThread,主线程就可以了。Edit:我应该继续这个想法。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之前被调用。在tl.set(pp);之后写new ChildThread(),应该可以看到值

    InheritableThreadLocal是胡说八道。除非做了什么恶意的事,否则我会避免

    总的来说,我强烈建议避免无必要的子类化和ThreadLocal