2011-06-24 42 views
3

當我強烈引用ThreadLocal保存資源,如下面的示例所示;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不是avaliable。我想知道,如果在某個時候沒有使用ThreadLocal對象,JVM將垃圾收集其引用,因此訪問嵌套的InputStream將無法​​使用。

javadoc表明:

線程本地 實例及其副本的所有受垃圾收集 (除非到 其他引用這些副本存在)。

如果確實如此,那麼如何確保副本始終可用?

回答

2

您的代碼的問題是您將保持文件指針打開。您可以將對象存儲在ThreadLocal中,但不要存儲需要關閉的資源,例如文件句柄,數據庫連接或其他資源。 ThreadLocal將超出範圍,因此一旦線程完成,就會被垃圾回收。在你的情況下,我將存儲從ThreadLocal中的InputStream獲得的內容,而不是流本身。
如果你想確保總是有東西可用,使用Singleton模式。瞭解Java EE環境中模式的侷限性。

+1

確實非常好的建議。謝謝 – Bitmap

3

threadlocal中的輸入流不是通過弱引用(由一個普通的強引用存儲的)存儲的,因此只要threadlocal對象本身可用,其輸入流也將可用,直到您調用remove()

但是threadlocal本身存儲爲每個線程的ThreadLocalMap中的弱引用。這個想法是每個Thread都有一個ThreadLocalMap的字段,其中所有的threadlocals都被帶有相應值的弱引用鍵入。

+0

@Surej非常有用 – Bitmap