【发布时间】:2017-12-20 12:32:30
【问题描述】:
我一直在阅读这个article 关于 Tomcat 中的 ThreadLocal 泄漏。第一个示例包含以下代码:
public class MyCounter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class MyThreadLocal extends ThreadLocal<MyCounter> {
}
public class LeakingServlet extends HttpServlet {
private static MyThreadLocal myThreadLocal = new MyThreadLocal();
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
MyCounter counter = myThreadLocal.get();
if (counter == null) {
counter = new MyCounter();
myThreadLocal.set(counter);
}
response.getWriter().println(
"The current thread served this servlet " + counter.getCount()
+ " times");
counter.increment();
}
}
它说所有的类都驻留在 webapp 中。然后它概述了类加载器(不是 ThreadLocal)泄漏的以下解释,我不明白:
如果 LeakingServlet 至少被调用一次并且线程 服务它没有停止,然后我们创建了一个类加载器泄漏!
泄漏是因为我们有一个 ThreadLocal 的自定义类 实例,以及绑定到 Thread 的值的自定义类。 实际上重要的是这两个类都是由 webapp 类加载器。
ThreadLocal 泄漏的解释很糟糕。如果服务请求的线程没有停止,我们怎么会有 ThreadLocal 泄漏(实际上文章说是类加载器泄漏)?这是否意味着,如果 Thread 是 Tomcat 线程池的一部分,并且由于 MyThreadLocal.remove() 尚未关闭,那么 MyCounter / MyThreadLocal 的 webapp 类加载器不能被垃圾收集,因为 Thread 返回到池中?打电话MyThreadLocal.remove() 会解决这个问题吗?我不明白。
【问题讨论】:
标签: java tomcat thread-local