JDK源碼分析-ScheduledExecutorService
- 2019 年 10 月 7 日
- 筆記
概述
介面的繼承結構如下:

下面分析這幾個介面的定義。
Executor
從名字來看,Executor 可譯為「執行器」,它的作用就是執行任務。該介面只有一個 execute 方法:
public interface Executor { // 執行給定的任務(Runnable) void execute(Runnable command); }
該方法的作用就是(在將來的某個時間)執行給定的命令,即實現了 Runnable 介面的對象。該命令可能在一個新的執行緒中執行,也可能在調用它的執行緒中執行。它的用法示例程式碼如下:
Executor executor = ...; executor.execute(new RunnableTask1()); executor.execute(new RunnableTask2());
PS: 前文分析的執行緒池類「JDK源碼分析-ThreadPoolExecutor」就是該介面的一個實現類。
ExecutorService
ExecutorService 可理解為「執行器服務」,它繼承自 Executor 介面,是對 Executor 的擴展,定義如下:
public interface ExecutorService extends Executor { // 關閉執行器服務。在此過程中之前提交的任務會執行,但不接收新的任務。若已關閉則無效。 void shutdown(); // 嘗試停止所有正在執行的任務,並返回等待執行的任務列表 List<Runnable> shutdownNow(); // 是否已關閉 boolean isShutdown(); // 是否已終止 boolean isTerminated(); // 阻塞,直到所有任務都在 shutdown 請求之後執行完畢,或者超時發生,或者當前執行緒被中斷(以先發生的情況為準) boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; // 提交一個 Callable 任務,有返回值 <T> Future<T> submit(Callable<T> task); // 提交一個 Runnable 任務,有返回值(執行成功後返回 result 值) <T> Future<T> submit(Runnable task, T result); // 提交一個 Runnable 任務,有返回值(執行成功後返回 null) Future<?> submit(Runnable task); // 執行提交的 Callable 任務列表,並返回對應的 Future 結果(即批量執行任務) <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; // 與上述方法類似,多了超時等待。若任務超時則完不成 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException; // 執行提交的 Callable 任務列表,返回已成功執行的任務的結果(無異常),若有的話。 <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; // 與上述方法類似,多了超時等待 <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
該介面與 Executor 相比,主要增加了有返回值的提交任務的方法。
PS: 可參考前文執行緒池 ThreadPoolExecutor 的相關分析;有關 Future 介面,前面「JDK源碼分析-FutureTask」也已分析,這裡不再贅述。
ScheduledExecutorService
ScheduledThreadPoolExecutor 介面繼承自 ExecutorService 介面,該介面定義了延遲執行的方法和周期性執行的方法,如下:
public interface ScheduledExecutorService extends ExecutorService { // 創建一次性操作(Runnable),該操作會在指定的延遲之後執行(其實就是創建了一個定時任務) public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); // 與上述方法類型,參數類型不同(Callable) public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); /* * 創建並執行一個周期性的任務 * 執行時間分別為 initialDelay, initialDelay + period, initialDelay + 2*period, 以此類推 * 若有異常則停止後續的執行;若任務執行時間超過其周期,則後續執行會延遲開始 */ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); /* * 創建並執行一個周期性的任務 * 該操作在給定的初始延遲之後首先啟用,然後在一次執行結束和下一次執行開始之間使用給定的延遲。 * 該方法與上述有些易混淆,不同的地方在於: * 上述方法是以每次開始執行的時間來計算; * 而本方法是以每次執行結束的時間和下次開始執行的時間計算 */ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); }
ScheduledExecutorService 可以做一些延遲執行的任務,或者周期性執行的任務,它在 JDK 中有一個實現類 ScheduledThreadPoolExecutor,後文再進行分析。
小結
本文主要分析了 Executor、ExecutorService 和 ScheduledExecutorService 這三個介面,它們之間是繼承關係,主要都是圍繞「執行任務」這個核心來的:
1. Executor 只有一個 execute 方法,只能執行 Runnable 任務,且無返回值;
2. ExecutorService 增強了 Executor 的功能,主要包括可以提交 Callable 任務,且有返回值;
3. ScheduledExecutorService 進一步增強了 ExecutorService 的功能,增加了延遲執行任務和周期性執行任務的功能。