ThreadLocal set() then immediately get() 并不总是取值
ThreadLocal set() then immediately get() doesn't always pick up the value
我无法可靠地获取刚刚设置的 ThreadLocal 值。我试图构建一个简单的例子来说明这个问题:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class WhosebugQuestion {
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
foo
foo
foo
foo
foo
null
foo
foo
null
值的位置每次都不同。我本以为他们都是 foo
。为什么我不能设置 threadLocal
然后立即读取我刚刚设置的值?它是在文档中的某处说的还是 JVM 错误?如果相关,我在 Windows.
上使用 Oracle Java JRE 1.8.0_172
您正在重复创建新的 ThreadLocal
。
您可以想象 ThreadLocal
像 Map
一样工作,以当前线程作为键。代码可能导致:
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());
});
我无法可靠地获取刚刚设置的 ThreadLocal 值。我试图构建一个简单的例子来说明这个问题:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class WhosebugQuestion {
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
foo
foo
foo
foo
foo
null
foo
foo
null
值的位置每次都不同。我本以为他们都是 foo
。为什么我不能设置 threadLocal
然后立即读取我刚刚设置的值?它是在文档中的某处说的还是 JVM 错误?如果相关,我在 Windows.
您正在重复创建新的 ThreadLocal
。
您可以想象 ThreadLocal
像 Map
一样工作,以当前线程作为键。代码可能导致:
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());
});