ThreadLocal资源

时间:2011-06-24 10:03:03

标签: java multithreading

当我强烈引用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;
 }
};

InputStreamThreadLocal保留的时间/范围不可用。我想知道在某些时候,如果没有使用ThreadLocal对象,JVM将垃圾收集其引用,因此对嵌套InputStream的访问将无法使用。

javadoc 表示;

  

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

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

2 个答案:

答案 0 :(得分:3)

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

但是threadlocal本身作为弱引用存储在每个线程的remove()中。这个想法是每个Thread都有一个ThreadLocalMap字段,其中所有的threadlocals都使用带有相应值的弱引用进行键控。

答案 1 :(得分:2)

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