未清除java中下一个线程的ThreadLocal值
我正在运行一个web服务,它至少接收200个RPS。基于该操作,我们使用以下代码为一些操作提供根访问权限
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()
会解决这个问题吗?如果是,如何进行
谢谢你的帮助
# 1 楼答案
你的
rootAccess
方法有两个问题:rootContext.set(null);
仍然保留与正在运行的线程关联的ThreadLocal
实例,最好执行rootContext.remove();
纠正这两点意味着将
rootAccess()
改为为什么
rootContext.set(null);
通常是个问题每个线程基本上保持一个类似于
Map<ThreadLocal, ?>
的数据结构,其中键是ThreadLocal
实例(rootContext
),值是通过rootContext.set(xx);
与之关联的值如果调用
rootContext.set(null);
,那么rootContext
仍在该映射中,因此执行此行的每个线程(来自线程池,意味着该线程处于长时间运行状态)都会保留对rootContext
的引用,这反过来可能会阻止类卸载如果调用
rootContext.remove();
,则rootContext
将从该映射中删除