【问题标题】:ThreadLocal set() then immediately get() doesn't always pick up the value [closed]ThreadLocal set() 然后立即 get() 并不总是获取值 [关闭]
【发布时间】:2018-08-03 15:05:22
【问题描述】:

我无法可靠地获取我刚刚设置的 ThreadLocal 值。我试图构建一个简单的例子来演示这个问题:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class StackOverflowQuestion {

    private static ThreadLocal<String> threadLocal;

    public static void main(String[] args) throws Exception {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            threadPool.execute(() -> {
                threadLocal = new ThreadLocal<>();
                threadLocal.set("foo");
                System.out.println(threadLocal.get());
            });
        }
        threadPool.shutdown();
        threadPool.awaitTermination(10, TimeUnit.SECONDS);
    }
}

输出是:

无效的








null 值的位置每次都不同。我本来希望他们都是foo。为什么我不能设置threadLocal 然后立即读取我刚刚设置的值?它是在文档中的某个地方这么说还是这是一个 JVM 错误?如果相关,我在 Windows 上使用 Oracle Java JRE 1.8.0_172。

【问题讨论】:

  • 你不应该在每个线程中创建一个新的 ThreadLocal 变量,你应该重用同一个实例,然后从不同的线程访问这个实例。
  • 因为第一个线程创建了一个新的 ThreadLocal 变量,在上面设置了一些东西,第二个线程创建了一个新的 ThreadLocal 变量,它没有任何内容,然后第一个线程打印该变量的内容(Nothing )。
  • 天啊!谢谢。
  • 他正在创建新的线程局部变量——你会得到一些不可预测的行为。实际的“ThreadLocal”引用本身应该由所有线程共享。
  • 不知道你为什么被否决,这是一个写得很好的问题。

标签: java multithreading thread-local


【解决方案1】:

您正在重复创建新的ThreadLocal

你可以想象ThreadLocalMap 一样工作,以当前线程为键。代码可能导致:

threadLocal = new ThreadLocal<>(); ----> one thread create an empty ThreadLocal
threadLocal.set("foo");
System.out.println(threadLocal.get()); ----> another thread get null

你可以改成:

threadPool.execute(() -> {
    threadLocal.set("foo");
    System.out.println(threadLocal.get());
});

【讨论】:

    猜你喜欢
    • 2017-11-21
    • 2016-03-19
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多