查看ThreadPoolExecutor的源碼發現,其提供了4個構造方法,如下:
其中典型使用
線程池會根據corePoolSize和maximumPoolSize自動地調整線程池大小
- 如果當前線程池的線程數少於corePoolSize線程正在運行的個數時, 無論已有線程是否空閒,都會新增一個線程
- 如果當前線程池的線程大於或者是等於corePooleSIze,並且任務隊列沒有滿時,將其提交給阻塞隊列排隊
- 如果線程池的大於或者等於corePoolSize,並且任務隊列滿時
如果當前線程池的線程 < maximumPoolSize,則新增線程
如果當前線程池的線程 = maximumPoolSize, 拒絕新增任何,可通過拒絕策略來進行控制
任務執行過程:
1. 提交新的任務時,判斷,是否達到了核心線程數量,如果達到,則創建一個工作線程來執行任務
2. 判斷工作隊列是否已經滿了, 如果沒滿,則將新提交的任務存儲在工作隊列中
3. 判斷是否達到了線程最大數量,如果沒有達到, 則創建一個新的工作線程來執行
4. 通過拒絕策略來處理任務
Executors常用工具類:
- newFixedThreadPool(int nThreads): 固定大小,任務隊列容量無界的線程池.corePoolSize=maximumPoolSize。
- newCachedThreadPool(): 適用於執行耗時較小的異步任務,大小無界的緩衝線程池,是一個同步隊列,keepAliveTime爲60秒,corePoolSize爲0,maximumPoolSize爲Integer.MAX_VALUE
- newSingleThreadExecutor():只有一個線程來執行無界任務隊列的單一線程池,與newFixedThreadPool(1)
的區別在於,單一線程池的池大小在newSingleThreadExecutor方法中硬編碼,不能改變 - newScheduledThreadPool(int corePoolSize) 定時執行任務的線程池。corePoolSize由參數指定,最大線程數爲Integer.MAX_VALUE
如何確定合適數量的線程:
計算型任務:cpu數量的1-2倍
IO型任務: 比計算型任務多一些線程,具體需要IO阻塞時長進行考量決定,可以考慮根據需要,在一個最小數量和最大數量間進行自動增減線程數