首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java ExecutorService 生命周期管理:shutdown、awaitTermination、isTerminated 全解析

     編輯:Java 相關知識

ExecutorService 繼承 Executor,新增生命周期控制方法,掌握其語義對生產環境優雅停機至關重要。

接口定義

public interface ExecutorService extends Executor {
    void shutdown();
    List shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
}

任務準備

// 短任務:生成10位隨機字符串
public class Task1 implements Callable { ... }

// 長任務:睡眠10秒
public class LongTask implements Callable {
    public String call() { TimeUnit.SECONDS.sleep(10); return "success"; }
}

方法逐一實測

1. shutdown():平滑關閉

  • 停止接受新任務
  • 等待已提交任務完成(執行中 + 隊列中)
  • 所有任務結束後進入 TERMINATED 狀態

2. awaitTermination(timeout, unit):阻塞等待終止

ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Task1());
service.submit(new LongTask()); // 第3個任務耗時10秒
service.shutdown();

while (!service.awaitTermination(1, TimeUnit.SECONDS)) {
    System.out.println("線程池未關閉");
}
System.out.println("線程池已關閉");

實測輸出:前 9 秒每秒打印「未關閉」,第 10 秒打印「已關閉」。

結論:shutdown() 不會中斷執行中任務,awaitTermination 僅作輪詢檢查。

3. shutdownNow():強制關閉

ExecutorService service = Executors.newFixedThreadPool(3);
for (int i=0; i<5; i++) service.submit(new LongTask());
List leftovers = service.shutdownNow(); // 立即關閉
System.out.println(leftovers.size()); // 輸出 2(隊列中等待的任務)

行為:

  • 嘗試中斷執行中任務(Thread.interrupt())
  • 取消隊列中未開始任務,返回列表
  • 不等待任務結束,直接進入關閉流程

4. isTerminated():終止狀態檢查

service.shutdown();
while (!service.isTerminated()) { /* 忙等待 */ }
// 退出循環時池確已 TERMINATED

配合長任務驗證:約 10 秒後返回 true。

5. isShutdown():關閉狀態檢查

調用 shutdown() 或 shutdownNow() 後立即返回 true,不代表任務已結束。

狀態流轉圖

RUNNING → shutdown() → SHUTDOWN → (任務完成) → TERMINATED
       → shutdownNow() → STOP → (中斷處理) → TERMINATED

最佳實踐

// 標準優雅停機模板
executor.shutdown();
try {
    if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
        executor.shutdownNow(); // 強制補刀
        if (!executor.awaitTermination(60, TimeUnit.SECONDS))
            log.error("Pool did not terminate");
    }
} catch (InterruptedException ex) {
    executor.shutdownNow();
    Thread.currentThread().interrupt();
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved