ThreadLocal InitialValue被调用两次

时间:2016-05-08 21:54:05

标签: java multithreading thread-local

我为所有线程设置了通用的ThreadLocal初始值。调用构造函数时,我更改了值并正确打印。但是当启动线程时,它又一次变为初始值?这是预期的吗?如果是,那么解释是什么?以下是我的两个班级。提前谢谢。

  1. MyRunnableThreadLocal.java

    public class MyRunnableThreadLocal implements Runnable {
    
    private ThreadLocal<String> threadLocal = new ThreadLocal<String>(){
        @Override protected String initialValue() {
            return "Thread Name not set yet";
        }
    };
    public MyRunnableThreadLocal(String threadName) {
        System.out.println(threadLocal.get());
        threadLocal.set(threadName);
        System.out.println("Thread name: " + threadLocal.get());
    }
    @Override
    public void run() {
        System.out.println(threadLocal.get());
        threadLocal.set(threadLocal.get() + " " + (Math.random() * 100D));
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
    
        System.out.println(threadLocal.get());
    }
    
    
    }
    
  2. ThreadLocalTest.java

    public class ThreadLocalTest {
    
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnableThreadLocal("Thread 1"));
        Thread t2 = new Thread(new MyRunnableThreadLocal("Thread 2"));
    
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    }
    
    }
    
  3. Out Put:

    Thread Name not set yet
    Thread name: Thread 1
    Thread Name not set yet
    Thread name: Thread 2
    Thread Name not set yet
    Thread Name not set yet
    Thread Name not set yet 20.24825634584746
    Thread Name not set yet 59.67633602373702
    

1 个答案:

答案 0 :(得分:2)

ThreadLocal是运行代码的线程的本地(以及与之关联的线程本地对象。)

Thread Name not set yet <= runs in main
Thread name: Thread 1   <= runs in main for the first MyRunnableThreadLocal object
Thread Name not set yet <= runs in main for the 2nd MyRunnableThreadLocal object
Thread name: Thread 2   <= runs in main for the 2nd MyRunnableThreadLocal object
Thread Name not set yet <= runs in the first thread for the first MyRunnableThreadLocal
Thread Name not set yet <= runs in the 2nd thread for the 2nd MyRunnableThreadLocal
Thread Name not set yet 20.24825634584746  <= runs in the first thread for the first MyRunnableThreadLocal
Thread Name not set yet 59.67633602373702  <= runs in the 2nd thread for the 2nd MyRunnableThreadLocal

所以你有三个线程和两个ThreadLocals。你的主要使用本地线程和你开始的两个线程各有一个值。

每次有新的ThreadLocal对象或新的Thread时,它都有一个新的初始值。

  

设置线程本地值怎么样?

在创建另一个ThreadLocal或在另一个线程中使用它之前,您只读过一次设置的值。

  

如果在主线程中运行前四行,那么#2行中的设置是否反映在第3行?

第3行是另一个ThreadLocal

中的MyRunnableThreadLocal对象
  

如果它正在处理第一个MyRunnableThreadLocal对象,那么为什么它没有反映在第5行或第6行?

第5行和第6行是这些ThreadLocals第一次在这些线程中使用,因此它们具有初始值。

注意:如果您使用InheritableThreadLocal,它会按预期执行。这是因为新线程&#34;继承&#34;由它的父线程设置的值。