現代機器CPU基本都是多核系統,利用多線程可以明顯提高系統的效率,但是如果不控制線程的使用,會給系統帶來嚴重的後果,因此,JDK提供了線程池供我們使用。有了線程池,每到達一個任務,從線程池調度一個空閒的線程來執行任務,避免了每次都要去創建線程帶來的開銷。
基本框架
上圖是JAVA線程池的基本框架,整個線程池基本上是根據這些類來設計的。
1. Executor
Executor是執行者的意思,JAVA線程池中一個核心思想就是將任務執行和任務提交解耦。執行者可以創建一個新的線程、通過線程池或者執行者本身來執行提交的任務。
以下是Executor接口的源碼:
public interface Executor {
//執行指定的任務,不一定在Executor本身所在的線程執行該任務,也可以通過新的線程或者線程池來執行。
//事實上,大部分情況都應該通過新的線程或者線程池執行該任務
void execute(Runnable command);
}
2. ExecutorService
ExecutorService是執行者服務,實現了Executor接口,主要提供了兩類方法:
- 終止線程的方法
- 能夠獲取任務執行結果的執行方法
以下是ExecutorService接口的源碼:
public interface ExecutorService extends Executor {
/**
* 啓動一次順序關閉,執行已經提交的任務,但不接受新的任務
*/
void shutdown();
/**
* 嘗試終止正在執行的任務,終止正在等待的任務,返回正在等待執行的任務列表
* 沒有辦法保證能夠停止正在運行的任務,如果線程不響應中斷的話,這些線程可能永遠不會終止
*/
List<Runnable> shutdownNow();
//返回該執行者是否已經關閉
boolean isShutdown();
//如果關閉後所有任務都已完成,返回true
//只有先調用shotdown或shutdownNow,該方法纔可能返回true
boolean isTerminated();
//收到shutdown請求後,該執行者阻塞,直到任務完成或者超時或者當前線程被中斷
//如果該執行者正常終止返回true,如果超時返回false
//如果線程被中斷,拋出中斷異常
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 提交一個有返回值的任務,返回一個帶有任務執行結果的對象
* 任務執行結果Future的get方法會阻塞,直到該任務執行完成
* 如果執行者不能調度執行該任務,拋出拒絕執行異常
*/
<T> Future<T> submit(Callable<T> task);
/**
* 該方法和上面的方法類似,因爲Runnable是沒有返回值的,因此這裏加了另一個參數result
* 表示任務的返回結果
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 提交一個沒有返回值的任務,返回代表任務返回結果的Future對象
*/
Future<?> submit(Runnable task);
//執行任務列表,返回任務的執行結果列表,返回任務結果的順序和執行任務的順序一致
<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;
//執行給定的任務列表,返回其中一個已經完成的任務結果
//如果沒有任務完成,拋出執行異常
<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;
}
3. AbstractExecutorService
該類實現了ExecutorService接口,爲線程池提供了默認實現,是線程池的基礎骨架。
4. ThreadPoolExecutor
該類就是JAVA的線程池,繼承了AbstractExecutorService。後面會專門解釋該類,現在暫時不說明。
5. ScheduledExecutorService
該接口提供了延時和週期性的任務執行功能。後面會專門說明。
6. ScheduledThreadPoolExecutor
帶延時和週期性任務執行的線程池。後面會專門說明。
7. Executors
線程池的靜態工廠,通過該靜態工廠返回常用的線程池。後面會專門說明。