当我强烈引用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;
}
};
在InputStream
中ThreadLocal
保留的时间/范围不可用。我想知道在某些时候,如果没有使用ThreadLocal
对象,JVM将垃圾收集其引用,因此对嵌套InputStream
的访问将无法使用。
javadoc 表示;
它的所有线程本地副本 实例受垃圾影响 集合(除非其他参考 这些副本存在)。
如果是这种情况,那么如何确保副本始终可用?
答案 0 :(得分:3)
threadlocal中的输入流不是通过弱引用存储的(它由普通的强引用存储),因此只要threadlocal对象本身可用,你的输入流也将可用,直到你调用{{3} }。
但是threadlocal本身作为弱引用存储在每个线程的remove()中。这个想法是每个Thread都有一个ThreadLocalMap字段,其中所有的threadlocals都使用带有相应值的弱引用进行键控。
答案 1 :(得分:2)
您的代码存在的问题是您将保持文件指针处于打开状态。您可以将对象存储在ThreadLocal中,但不存储诸如文件句柄,数据库连接或其他需要关闭的资源等资源。 ThreadLocal将超出范围,因此一旦Thread完成就会被垃圾收集。在您的情况下,我将存储您从ThreadLocal中的InputStream获取的内容,但不存储流本身。
如果您想确保某些内容始终可用,请使用Singleton模式。请注意Java EE环境中模式的局限性。