2016-02-04 422 views
0

我有第三方Java庫提供資源。在Java中,如何在線程完成時關閉ThreadLocal資源

TheResource resource = TheResource.create() 

一段時間後,當我與資源完成的,我應該關閉資源

resource.close() 

據庫文件,我創建資源是一個ThreadLocal變量。這意味着資源是爲每個線程創建的,並且它堅持線程。我的問題是,關聯線程完成後是否可以自動調用close()方法?我想我可以做到這一點,如果線程是我自己的自定義線程,因爲我可以參與線程的生命週期。但我的問題是關於系統提供的線程。

例如,在Android的SyncAdapter中爲您提供了一個線程。我不知道線程是如何完成的。我想知道在線程生命週期中是否存在某種「鉤子」機制,以便我可以關閉線程的ThreadLocal資源。

+1

我不跟着你。你說圖書館創建了一個資源,但是圖書館的文檔說_you_必須提供一個'ThreadLocal'?也許如果你提供了一些代碼示例或文檔中的一些直接引用... –

+0

我想明白你正在做什麼,但也是一個非常困難,如果不是不可能沒有一些奇怪的Java黑魔法。即使你能夠監聽線程來完成,你也必須在死的線程上下文中調用ThreadLocal.remove()。也許'Object.finalize()'是最接近你可以得到的,但它需要子類化該上下文線程。 – Whome

回答

0

該資源可能不是靜態創建的,而是ThreadLocal,因此多個線程可以獨立使用自己的資源。

因此你的線程調用TheResource.create()是那個線程。第二次和第三次致電create在同一線程上執行此操作是您的責任。然後在該線程的末端close - 在同一線程上。

(可能關閉並不需要在同一個線程上完成的。)

你可以裝在一個班。


FPR例如:

public class ResourceManager { 

    private static final Set<TheResource> resources = new HashSet<>(); 

    public static TheResource create() { 
     TheResource res = TheResource.create(); 
     // Not needced: Thread thread = Tread.currentThread(); 
     resources.add(res); 
     return res; 
    } 

    public static void shutdown() { 
     resources.forEach(TheResource::close); 
    } 
} 

而且在應用程序關閉:

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { ResourceManager.shutDown(); } 
}); 
+0

我不確定我是否正確理解您的答案。讓我以這種方式提出我的問題:有一種方法可以在線程完成時以自定義方式清理ThreadLocal變量,前提是線程由系統爲您提供。 – Jake

+0

添加了一個示例。 –

+0

這是「如何通過三個簡單步驟創建內存泄漏」的示例代碼。只在最後獨立於實際生命週期清理資源通常是不好的行爲。 – Voo