![](/img/trans.png)
[英]Will the ThreadLocal object be cleared after thread returned to Thread Pool?
[英]ThreadLocal value not cleared for the next thread in java
我正在运行 web 服务,该服务至少接收 200 RPS。 基于该操作,我们为少数操作提供 root 访问权限,并使用以下代码。
private static final ThreadLocal<String> rootContext = new ThreadLocal<String>();
public Optional<String> getRunner() {
if (rootContext.get() != null) {
return rootContext.get();
} else {
return getCurrentRunner();
}
}
public void rootAccess(Runnable runnable) {
rootContext.set("root");
runnable.run();
rootContext.set(null);
}
getCurrentRunner()
方法将根据请求返回实际的调用者。 问题是 200 个请求中有 1 个返回root
而不是实际的调用者。
我注意到的一件事是,我没有使用 threadlocal.remove(),而是将该值设置为 null。 预计 getRunner() rootContext.get() != null
条件将失败并返回实际的调用者。
如何解决这个问题? 设置rootContext.remove()
会解决这个问题吗? 如果是,如何?
谢谢您的帮助
您的rootAccess
方法有两个问题:
rootContext.set(null);
仍然保持与正在运行的线程关联的ThreadLocal
实例,最好做rootContext.remove();
更正这两点意味着将rootAccess()
更改为
public void rootAccess(Runnable runnable) {
rootContext.set("root");
try {
runnable.run();
} finally {
rootContext.remove();
}
}
为什么是rootContext.set(null);
一般有问题吗?
每个线程基本上都保留一个类似于Map<ThreadLocal, ?>
的数据结构,其中键是您的ThreadLocal
实例( rootContext
),值是您通过rootContext.set(xx);
如果你调用rootContext.set(null);
那么rootContext
仍然在 map 中,因此执行此行的每个线程(来自线程池,意味着线程长时间运行)都会保留对 rootContext 的引用,这反过来可能会阻止rootContext
卸载。
如果你调用rootContext.remove();
rootContext 从rootContext
中删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.