## 3.2 Java的Executor框架
Java平臺本身提供了Executor框架用來幫助我們使用線程池。

Executor框架最核心的類是ThreadPoolExecutor,這是各個線程池的實現類,有如下幾個屬性:
* corePool:核心線程池的大小 m
* maximumPool:最大線程池的大小
* keepAliveTime: 休眠等待時間
* TimeUnit unit : 休眠等待時間單位,如微秒/納秒等
* BlockingQueue workQueue:用來保存任務的工作隊列
* ThreadFactory: 創建線程的工廠
* RejectedExecutionHandler:當線程池已經關閉或線程池Executor已經飽和,execute()方法將要調用的Handler
通過Executor框架的根據類Executors,可以創建三種基本的線程池:
* FixedThreadPool
* SingleThreadExecutor
* CachedThreadPool
### FixedThreadPool
FixedThreadPool被稱為可重用固定線程數的線程池。
```
// 獲取fixedThreadPool
ExecutorService fixedThreadPool=Executors.newFixedThreadPool(paramInt);
//內部會調用下面的方法,參數 corePoolSize、maximumPoolSize、keepAliveTime、workQueue
return new ThreadPoolExecutor(paramInt, paramInt, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
```
FixedTheadPool設置的線程池大小和最大數量一樣;keepAliveTime為0,代表多余的空閑線程會立刻終止;保存任務的隊列使用LinkedBlockingQueue,當線程池中的線程執行完任務后,會循環反復從隊列中獲取任務來執行。
FixedThreadPool適用于限制當前線程數量的應用場景,適用于`負載比較重`的服務器。
### SingleThreadExecutor
SingleThreadExecutor的核心線程池數量corePoolSize和最大數量maximumPoolSize都設置為1,適用于需要`保證順序執行`的場景
```
ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
```
### CachedThreadPool
CachedThreadPool是一個會根據需要創建新線程的線程池,適用于短期異步的小任務,或`負載教輕`的服務器。
```
ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());
```
SynchronousQueue是一種阻塞隊列,其中每個插入操作必須等待另一個線程的對應移除操作 ,反之亦然。corePoolSize是0,maximumPoolSize都最大,無界的。keepAliveTime為60秒,空閑線程超過60S會被終止。
### ScheduleThreadPoolExecutor
ScheduleThreadPoolExecutor和Timer類似,可以設置延時執行或周期執行,但比Timer有更多的功能。Timer和TimerTask只創建一個線程,任務執行時間超過周期會產生一些問題。Timer創建的線程沒有處理異常,因此一旦拋出非受檢異常,會立刻終止。
```
ScheduledThreadPoolExecutor executor=new ScheduledThreadPoolExecutor(5);
//可以直接執行
executor.execute(new JobTaskR("executor", 0));
executor.execute(new JobTaskR("executor", 1));
System.out.println("5S后執行executor3");
//隔5秒后執行一次,但只會執行一次。
executor.schedule(new JobTaskR("executor", 3), 5, TimeUnit.SECONDS);
System.out.println("開始周期調度");
//設置周期執行,初始時6S后執行,之后每2s執行一次
executor.scheduleAtFixedRate(new JobTaskR("executor", 4), 6, 2, TimeUnit.SECONDS);
```
scheduleAtFixedRate或者scheduleWithFixedDelay方法,它們不同的是前者以固定頻率執行,后者以相對固定延遲之后執行。