【发布时间】:2019-07-10 13:58:15
【问题描述】:
我在下面的博客中了解了 ThreadLocals 的概念:
https://www.baeldung.com/java-threadlocal
上面写着“不要将 ThreadLocal 与 ExecutorService 一起使用”
它说明了下面使用 ThreadLocals 的示例。
public class ThreadLocalWithUserContext implements Runnable {
private static ThreadLocal<Context> userContext
= new ThreadLocal<>();
private Integer userId;
private UserRepository userRepository = new UserRepository();
@Override
public void run() {
String userName = userRepository.getUserNameForUserId(userId);
userContext.set(new Context(userName));
System.out.println("thread context for given userId: "
+ userId + " is: " + userContext.get());
}
// standard constructor
}
在文末提到:
如果我们想使用 ExecutorService 并向其提交 Runnable,使用 ThreadLocal 将产生不确定的结果——因为我们不能保证给定 userId 的每个 Runnable 操作每次都会由同一个线程处理它被执行了。
因此,我们的 ThreadLocal 将在不同的 userId 之间共享。这就是为什么我们不应该将 TheadLocal 与 ExecutorService 一起使用。只有在我们完全控制哪个线程将选择执行哪个可运行操作时才应该使用它。
这个解释对我来说是一个保镖。我试图专门针对这一点在网上做一些研究,但我没有得到太多帮助,请高手详细说明一下上述解释吗?是作者的观点还是真正的威胁?
【问题讨论】:
-
只要在每个任务开始的时候初始化ThreadLocal就可以了。
-
为什么?如果您使用的是
Executor Service,则您已经拥有Runnables或Callables,您可以将数据保存在其中。不需要ThreadLocal。
标签: java multithreading thread-local