Executor框架簡介
Executor框架的兩級調度模型
在HotSpot VM的線程模型中,Java線程被一對一映射為本地操作系統線程。Java線程啟動時會創建一個本地操作系統線程;當Java線程終止時,這個操作系統線程也會被回收。操作系統會調用所有線程並將他們分配給可用的CPU。
可以將此種模式分為兩層,在上層,Java多線程程序通常把應用程序分解為若干任務,然后使用用戶級的調度器(Executor框架)將這些任務映射為固定數量的線程;在底層,操作系統內核將這些線程映射到硬件處理器上。
#### **Executor框架的結構** **Executor框架主要由3大部分組成:**
- 任務: 包括被執行的任務需要實現的接口:Runable 接口、Callable接口;
- 任務的執行: 包括任務執行機制的核心接口Executor,以及繼承自Executor的ExecutorService接口。Executor框架有兩個關鍵類實現了ExecutorService接口:ThreadPoolExecutor 和 ScheduledThreadPoolExecutor、ForkJoinPool;
- 任務的異步計算結果: 包括Future接口和實現Future接口的FutureTask類、ForkJoinTask類。
注意一下:此圖不完整,Executor框架的成員還包括: CompletionService
、ExecutorCompletionService
、ForkJoinTask、ForkJoinPool
;
#### **Executor框架的成員介紹** ##### **1、Runnable接口 和 Callable接口** Runnable接口和Callable接口的實現類,都可以被ThreadPoolExecutor或Scheduled- ThreadPoolExecutor執行。 它們之間的區別是Runnable不會返回結果,而Callable可以返回結 果。 除了可以自己創建實現Callable接口的對象外,還可以使用工廠類Executors來把一個 Runnable包裝成一個Callable。
//Executors方法
public static Callable<Object> callable(Runnable task);
public static <T> Callable<T> callable(Runnable task, T result);
2、Executor、ExecutorService、AbstractExecutorService、ScheduledExecutorService
Executor 接口: 是Executor框架的基礎,它將任務的提交與任務的執行分離開來。
ExecutorService 接口: 擴展了Executor接口,提供了管理終止的方法(shutdown( ) ,etc),以及可為跟蹤一個或多個異步任務執行狀況而生成 Future 的方法。
AbstractExecutorService 類: 提供 ExecutorService 執行方法的默認實現。
ScheduledExecutorService 接口: 一個特殊的 ExecutorService,提供了 可安排在給定的延遲后運行或定期執行的命令。
3、ThreadPoolExecutor
ThreadPoolExecutor通常使用工廠類Executors來創建。Executors可以創建3種類型的ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool和CachedThreadPool。
以下是這三種線程池的應用場景說明:
- FixedThreadPool適用於為了滿足資源管理的需求,而需要限制當前線程數量的應用場
景,它適用於負載比較重的服務器。
- SingleThreadExecutor適用於需要保證順序地執行各個任務;並且在任意時間點,不會有多
個線程是活動的應用場景。 - CachedThreadPool是大小無界的線程池,適用於執行很多的短期異步任務的小程序,或者
是負載較輕的服務器
4、ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor通常使用工廠類Executors來創建。Executors可以創建2種類
型的ScheduledThreadPoolExecutor,如下。
- ScheduledThreadPoolExecutor:包含若干個線程的ScheduledThreadPoolExecutor。
- SingleThreadScheduledExecutor:只包含一個線程的ScheduledThreadPoolExecutor。
5、Future 接口
Future接口和實現Future接口的FutureTask類用來表示異步計算的結果。當我們把Runnable
接口或Callable接口的實現類提交(submit)給ThreadPoolExecutor或
ScheduledThreadPoolExecutor時,ThreadPoolExecutor或ScheduledThreadPoolExecutor會向我們
返回一個FutureTask對象。下面是對應的API。
<T> Future<T> submit(Callable<T> task)
<T> Future<T> submit(Runnable task, T result)
Future<> submit(Runnable task)
有一點需要讀者注意,到目前最新的JDK 8為止,Java通過上述API返回的是一個
FutureTask對象。但從API可以看到,Java僅僅保證返回的是一個實現了Future接口的對象。在將
來的JDK實現中,返回的可能不一定是FutureTask
參考資料
- 《java並發編程的藝術》