Java執行緒池ThreadPoolExecutor面試總結思維導圖速記
阿新 • • 發佈:2020-07-28
## 優點
***
1. 降低資源消耗,通過重複利用已建立的執行緒降低執行緒建立和銷燬造成的消耗。
2. 提高響應速度,當任務到達時,可以不需要等待執行緒建立就能立即執行。
3. 提高執行緒的可管理性
## 類關係
***
接 Executor 一個無返回值的execute方法
接 ExecutorService 返回值為Future型別的submit方法
類 AbstractExecutorService
類 ThreadPoolExecutor
## 建立
***
### ThreadPoolExecutor類
包含引數
```java
corePoolSize: 核心執行緒數最大值
maximumPoolSize: 最大執行緒數大小
keepAliveTime: 非核心執行緒空閒的存活時間大小
unit: 執行緒空閒存活時間單位
workQueue: 存放任務的阻塞佇列
threadFactory: 用於設定建立執行緒的工廠
handler: 線城池的飽和策略事件
```
引數workQueue有如下幾種佇列
1. ArrayBlockingQueue; 必須帶參構造,陣列,預設非公平可指定,FIFO
2. LinkedBlockingQueue; 可帶參構造,大小預設int最大,FIFO
3. SynchronousQueue;不儲存元素,每個插入操作必須等到另一個執行緒呼叫移除操作,否則堵塞
4. PriorityBlockingQueue;優先順序,陣列
5. DelayQueue; 基於PriorityQueue,延時阻塞佇列,只有當其指定的延遲時間到了,才能夠從佇列中獲取到該元素。
引數hander有如下幾種
1. AbortPolicy 丟棄任務並拋異常,預設
7. DiscardPolicy 直接丟棄任務
8. DiscardOldestPolicy 丟棄佇列最前面的任務,然後重新嘗試執行任務(重複此過程)
9. CallerRunsPolicy 由呼叫執行緒處理該任務
### Executors類
阿里巴巴開發規範不允許使用Executors去建立,因為佇列OOM。
主要有如下幾種
1. newCachedThreadPool():一個任務建立一個執行緒,使用SynchronousQueue,用於併發執行大量短期的小任務。
2. newFixedThreadPool(nThreads):所有任務使用固定大小的執行緒池,使用LinkedBlockingQueue,適用執行長期的任務
3. newSingleThreadExecutor():只有一個執行緒的執行緒池,使用LinkedBlockingQueue,適用於序列執行任務的場景,
## 執行流程
***
在 execute() 中實現,當提交一個執行緒時
1. 如果正在執行的執行緒數 < coreSize,馬上建立執行緒執行該task,不排隊等待;
2. 如果正在執行的執行緒數 >= coreSize,把該task放入佇列;
3. 如果佇列已滿 && 正在執行的執行緒數 < maximumPoolSize,建立新的執行緒執行該task;
4 . 如果佇列已滿 && 正在執行的執行緒數 >= maximumPoolSize,執行緒池呼叫handler的reject方法拒絕本次提交。
## 異常捕獲
****
預設不捕獲異常,捕獲方法如下
1. try-catch
2. submit執行,Future.get接受異常
3. 重寫ThreadPoolExecutor的afterExecute方法,處理傳遞的異常引用
4. 為工作者執行緒設定UncaughtExceptionHandler,在uncaughtException方法中處理異常
## 執行緒池狀態
****
**running**
該狀態的執行緒池會接收新任務,並處理阻塞佇列中的任務;
1. shutdown() -> shutdown
2. shutdownNow() -> stop
**shutdown**
該狀態的執行緒池不會接收新任務,但會處理阻塞佇列中的任務;
1. 佇列為空,並且執行緒池中執行的任務也為空,進入tidying狀態;
**stop**
該狀態的執行緒不會接收新任務,也不會處理阻塞佇列中的任務,而且會中斷正在執行的任務;
1. 執行緒池中執行的任務為空,進入tidying狀態;
**tidying**
該狀態表明所有的任務已經執行終止,記錄的任務數量為0。
1. terminated() -> terminated
**terminated**
該狀態表示執行緒池徹底終止
## 執行緒大小設定
****
1. 如果是CPU密集型任務,就需要儘量壓榨CPU,參考值可以設為 N(cpu) + 1
2. 如果是IO密集型任務,參考值可以設定為2 * N(cpu)
## 思維導圖(右鍵另存為下載)
![在這裡插入圖片描述](https://images.cnblogs.com/cnblogs_com/neverth/1592425/o_200727154751Java%E5%B9%B6%E5%8F%91-min.png)
## 喜歡可以點個贊,