簡體   English   中英

在Java中關閉ExecutorService的最佳方法

[英]Best way to shutdown ExecutorService in Java

我正在嘗試用Java編寫異步編程,我正在使用ExecutorService創建一個由多個線程支持的池來提交多個可調用任務,但我對如何關閉ExecutorService幾乎沒有疑問。

這是我的原始代碼:

ExecutorService executorService = Executors.newFixedThreadPool(10);

Future<String> f = executorService.submit(() -> {/*do something*/});

executorService.shutdown();

String result = f.get();
System.out.println(result);

這很好用,執行程序在線程完成后關閉。 但我擔心如果寫錯了可調用任務f.get()的代碼永遠需要,程序將永遠停止並永遠不會退出。

有了擔心,這是我的第二次嘗試:

ExecutorService executorService = Executors.newFixedThreadPool(10);

Future<String> f = executorService.submit(() -> {/*do something*/});

executorService.shutdown();

if(!executorService.awaitTermination(10, TimeUnit.SECONDS)){
    executorService.shutdownNow();
}

String result = f.get();
System.out.println(result);

使用上面的代碼,我可以確保線程在10秒后關閉。 但實際上程序被阻止了10秒,線程可能只用了5秒鍾。

我的問題是如何設置強制關閉池中的線程的時間,以便我不需要顯式使用awaitTermination來阻止程序。

但我擔心如果寫錯了可調用任務f.get()中的代碼永遠需要,程序將永遠停止並永遠不會退出。

那是一個錯誤。 你需要確保不會發生這種情況。

使用上面的代碼,我可以確保線程在10秒后關閉

不,你不能。 甚至shutdownNow()實際上並不保證執行程序線程被關閉( 文檔 ):

除盡力嘗試停止處理主動執行任務之外,沒有任何保證。 例如,典型的實現將通過Thread.interrupt()取消,因此任何未能響應中斷的任務都可能永遠不會終止。

ThreadPoolExecutor試圖通過中斷所有工作線程來“立即關閉”。 您需要確保您的任務正確處理中斷

一旦您的任務正確停止,您就可以根據應用程序和正在關閉的任務來估計關閉所需的時間。 然后你可以正常關機:

  • 調用shutdown()
  • 使用awaitShutdown()等待一段合理的時間有序關閉
  • 如果執行程序仍在運行,請調用shutdownNow()並處理它返回的任何未完成的任務。

您的程序不應該在第二個版本中被阻止10秒。 只有當你的線程沒有在10秒內終止時,它應該等待10秒。 如果您的線程在10秒內未完成,您的執行程序服務將暫停所有線程的終止。 來自Java文檔

/ ** *阻塞,直到所有任務在關閉*請求之后完成執行,或發生超時,或者當前線程被*中斷,以先發生者為准。 * * @param超時最長等待時間* @param單位超時參數的時間單位* @return {@code true}如果此執行程序終止,* {@code false}如果超時之前超時* @throws InterruptedException如果在等待時被打斷* /

除了上面的答案,我想補充以下幾點。

您可以在調用get()方法之前調用Future api的isDone()方法,以驗證是否在通過ExcuterService api的awaitTermination方法等待任務完成時完成任務。

但是我建議使用awaitTermination和shutdownNow而不是使用

get(long timeout,TimeUnit unit)[如果需要,最多在給定時間內等待計算完成,然后檢索其結果(如果可用)。

未來的API。 如果發生超時,它將拋出TimeoutException,您可能會嘗試調用shutdownNow

您還可以通過ExecuterService API的isShutdown()方法檢查關閉狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM