0

我有一個Java ExecutorService(固定線程池爲1),我將可運行任務傳遞給將來執行。每個任務通常在10秒內完成。 ExecutorService只是完成這些任務。如果我關閉我的應用程序,我運行以下;Java ExecutorService關閉現在需要時代

if (taskProcessor != null) { 
    taskProcessor.shutdownNow(); 
    while (!taskProcessor.isTerminated()) { 
     // Wait For All Submitted Tasks To Finish 
    } 
} 

問題是,它似乎需要一個年齡就關機,有時可能需要幾分鐘,有時它似乎永遠不會關機,有時在幾秒鐘的停機!執行程序隊列中的任何時候都可能有大約2000個任務,但我只是希望它完成當前正在執行和退出的任務。我在這裏做錯了什麼?

+0

忙碌的等待幾乎不是一個好主意。 – Raedwald

回答

0

這一切都取決於正在執行的任務。 ThreadPoolExecutor不會結束,直到所有任務結束。 shutdownNow()中斷所有任務,但任務可能會忽略它。

+0

謝謝,我會添加一些調試,並嘗試探索是否這是發生了什麼。我有一個計時器附加到每個任務來監視任務超時,所以想知道這是問題發生的地方,正在運行的任務由於計時器而忽略中斷。 – Ashley

+0

請注意,任務只能對中斷進行響應,如果它被設計爲 –

+0

我認爲這是問題。我只是添加一個捕獲InterruptedException並用一個while循環包裝任務。希望我的調試能在一瞬間進一步闡明。 – Ashley

0

您沒有按照正確的順序關閉ExecutorService

你要叫shutdownshutdownNowawaitTermination按照特定的順序所推薦的oracle

void shutdownAndAwaitTermination(ExecutorService pool) { 
    pool.shutdown(); // Disable new tasks from being submitted 
    try { 
    // Wait a while for existing tasks to terminate 
    if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { 
     pool.shutdownNow(); // Cancel currently executing tasks 
     // Wait a while for tasks to respond to being cancelled 
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) 
      System.err.println("Pool did not terminate"); 
    } 
    } catch (InterruptedException ie) { 
    // (Re-)Cancel if current thread also interrupted 
    pool.shutdownNow(); 
    // Preserve interrupt status 
    Thread.currentThread().interrupt(); 
    } 
} 
0

您可以不必你的代碼做忙等待做的更好。這將釋放一個CPU來完成任務。並防止isTerminated使用的任何鎖的爭用。