[英]Properly managing memory when using ExecutorService
有一個名為“ ConcurrencyUtils”的實用程序類,它在內部使用ExecutorService
private static final ExecutorService executor = Executors.newCachedThreadPool(new CommonPoolThreadFactory());
如您所見,它使用了一個線程池,該池將按需添加線程。 問題是如果該池中至少有一個線程(如果至少使用util一次),則當主方法執行完成時應用程序卻沒有關閉,因為線程仍然存在並且沒有被垃圾回收...
最初我嘗試使用
public static void close(){
executor.shutdown();
}
並在程序自然停止執行時調用它。 但是不能保證main方法是最后一個要完成的方法,並且在應用程序終止之前可能還有其他應完成的任務,因此我不知道在哪里調用“ close()”來清理util中的線程。 。
我想知道社區是否可以提示我一種更聰明/更清潔的方式來實現這一目標?
ConcurrencyUtil旨在可以在任何地方使用,我無法創建它的實例,我需要它通過靜態而非實例方法提供其接口。
讓我詳細解釋這種情況,ConcurrencyUtil有自己的pool實現,它提供了有用的方法來鏈接多個可運行對象並在paralell中執行它們,或者讓其中一些等待其他對象完成然后執行...這確實很重要是一個實用程序類,這樣,無論何時您想要使用async()或chain(),都不用擔心它是如何工作的。
現在的示例代碼:
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("hoooooooooooook");
}
});
ConcurrencyUtil.chain()
.add(()->System.out.println("task 1"))
.add(()->System.out.println("task 2"))
.execute()
.join();
System.out.println("main finish");
}
執行此操作時,我將得到以下信息:
created new thread with name [common-pool : thread-1]
created new thread with name [common-pool : thread-2]
task 1
task 2
main finish
如您所見,線程池創建了兩個線程並執行並發任務,但那些工作線程仍在活動(處於睡眠狀態)等待新任務,這就是為什么在主要執行完成后應用程序仍在運行...並且關閉鈎子也無法正常工作因為(我想)應用程序被認為是活着的...
現在,由於我無法保證main方法是我的退出點(例如,如果我刪除.join(),它可能是完成執行的可運行對象),這就是為什么我無法最終阻止並關閉ConcurrencyUtil的原因...
有什么想法可以正確完成嗎?
應用程序設計的正確方法是引入一個明確的關閉過程,該過程在任何適當的地方都可以調用。 然后,此過程可以在您的執行程序服務上調用shutdown()
,然后調用awaitTermination()
。 查看ExecutorService
的Javadoc中的完整代碼示例。
除了常規關閉協議之外,您還可以提供JVM關閉鈎子,它將再次啟動相同的關閉過程。 您永遠不應依賴該機制,但是在發生不可預測的故障時這是一件好事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.