【问题标题】:Which is the best way to remove references of Thread Local objects [closed]哪个是删除线程本地对象引用的最佳方法[关闭]
【发布时间】:2016-06-12 05:58:31
【问题描述】:

我的 Web 应用程序中有一个静态 ThreadLocal 对象,我在处理请求之前使用 Web servlet 过滤器类中的一些默认值进行初始化。在应用程序中,其他几个类(如处理器)使用并更新其值。我在一些文章中读到,尽管请求过程已完成,但使用 ThreadLocal 创建的对象仍与线程相关联因为线程维护在由容器管理的池中。如果没有从 ThreadLocal 变量中删除对象,这会导致内存泄漏。

在这方面我有两个问题。

  1. 在以下选项中,哪一个是删除其引用以防止内存泄漏的最佳且正确的方法。

    ThreadLocal obj;
    1) obj.remove(); // remove the contents of ThreadLocal.
    2) obj.set(""); // set some default value
    3) obj.set(null); // set null
    

【问题讨论】:

  • (1)的答案是(1),或者让线程退出。第二个问题看不懂。
  • 改写了我的第二个问题?

标签: java multithreading web servlet-filters thread-local


【解决方案1】:

使用ThreadLocal#remove()。然而,这不是您主要关心的问题。您主要关心的应该是您可以保证在特殊情况下也会调用remove()。正确的做法是在创建和委托 TLS 的try 块的finally 中执行remove()。

YourContext context = null;
try {
    context = YourContext.create(request, response);
    chain.doFilter(request, response);
} finally {
    if (context != null) context.release(); // Invokes remove().
}

如果您已经使用 Java 7+,最好让您的上下文实现 AutoCloseable,其中 close() 调用 remove(),然后使用 try-with-resources 块。

try (YourContext context = YourContext.create(request, response)) {
    chain.doFilter(request, response);
}

有关如何创建YourContext 的更多提示,请访问Retrieving Web Session from a POJO Outside the Web Container。

【讨论】:

  • 我仍在使用 Java 6 并且在 Filter 类中,我在链调用之前和之后进行初始化和删除。你能帮我解决我的第二个问题吗?
  • 作为回答,删除必须发生在 finally 块中。至于第二个问题,您应该每个问题问一个问题。 GC 问题至少与 TLS 问题无关。如果一个对象没有任何引用,它就有资格进行 GC。就这么简单。
猜你喜欢
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多