何时以及如何使用 ThreadLocal 变量?

新手上路,请多包涵

我什么时候应该使用 ThreadLocal 变量?

它是如何使用的?

原文由 Sasha 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 337
2 个回答

一种可能的(也是常见的)用途是当您有一些不是线程安全的对象时,但您希望避免 同步 对该对象的访问(我正在看着您, SimpleDateFormat )。相反,给每个线程它自己的对象实例。

例如:

 public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

文档

原文由 overthink 发布,翻译遵循 CC BY-SA 3.0 许可协议

由于 ThreadLocal 是对给定 Thread 中数据的引用,因此在使用 ThreadLocal 服务器使用线程池应用程序时,您可能会遇到类加载泄漏。 You need to be very careful about cleaning up any ThreadLocal s you get() or set() by using the ThreadLocal ’s remove() 方法。

如果您在完成后不清理,它持有的对作为部署的 web 应用程序的一部分加载的类的任何引用将保留在 永久堆中,并且永远不会被垃圾收集。重新部署/取消部署 webapp 不会清除每个 Thread 对您的 webapp 类的引用,因为 Thread 不属于您的 webapp。每个连续的部署都将创建一个永远不会被垃圾收集的类的新实例。

由于 java.lang.OutOfMemoryError: PermGen space ,你最终会遇到内存不足的异常,并且在一些谷歌搜索之后可能只会增加 -XX:MaxPermSize 而不是修复错误。

如果您确实遇到了这些问题,您可以通过使用 Eclipse 的内存分析器 和/或遵循 Frank Kieviet 的指南 进来确定哪个线程和类保留了这些引用。

更新:重新发现了 Alex Vasseur 的博客条目,它帮助我找到了一些 ThreadLocal 我遇到的问题。

原文由 Phil M 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题