【问题标题】:ThreadLocal Resource线程本地资源
【发布时间】:2011-06-24 10:03:02
【问题描述】:

当我强烈引用ThreadLocal 持有资源时,如下例所示;

private final static ThreadLocal<InputStream> resource = new ThreadLocal<InputStream>()
{
@Override
protected InputStream initialValue()
{
  ClassLoader loader = Thread.currentThread().getContextClassLoader();
  InputStream input = loader.getResourceAsStream("doc/doc.xml");
  if (input == null) throw new RuntimeException("Could not locate doc.xml");
  return input;
 }
};

ThreadLocal 中保存的InputStream 在什么时间/范围内不可用。我想知道当ThreadLocal 对象没有被使用时,JVM 是否会垃圾收集它的引用,因此无法访问嵌套的InputStream

javadoc 表示;

它的所有线程本地副本 实例受到垃圾 集合(除非其他参考 这些副本存在)。

如果是这种情况,那么如何确保副本始终可用?

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    threadlocal 中的输入流不是通过弱引用存储的(它由普通的强引用存储),因此只要 threadlocal 对象本身可用,您在其中的输入流也将可用,直到您调用 remove()

    但是 threadlocal 本身作为弱引用存储在每个线程的 ThreadLocalMap 中。这个想法是每个线程都有一个用于 ThreadLocalMap 的字段,其中所有线程本地都使用具有相应值的弱引用作为键。

    【讨论】:

      【解决方案2】:

      您的代码的问题是您将保持文件指针打开。您可以将 Objects 存储在 ThreadLocal 中,但不要存储资源,例如文件句柄、数据库连接或其他需要关闭的资源。 ThreadLocal 将超出范围,因此一旦 Thread 完成就会被垃圾收集。在您的情况下,我会将您从 InputStream 获得的内容存储在 ThreadLocal 中,而不是流本身。
      如果您想确保某些东西始终可用,请使用单例模式。请注意该模式在 Java EE 环境中的局限性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        相关资源
        最近更新 更多