執行緒池的選用與執行緒數的指定
阿新 • • 發佈:2019-01-04
1、選用的兩個角度
- 高效能:將提交到執行緒池中的任務直接交給執行緒去處理(前提:執行緒數小於最大執行緒數),不入隊
- 緩衝執行:希望提交到執行緒池的任務儘量被核心執行緒(corePoolSize)執行掉
2、高效能
- 佇列:SynchronousQueue
- 最大執行緒數:一般設為Integer.MAX_VALUE(整數最大值),防止回絕任務
- 典型案例:newCachedThreadPool
- 尤其適合於執行耗時短的任務
注意:
- 設定好閒置失效時間,keepAliveTime,用於避免資源大量耗費
- 對於出現大量耗時長的任務,容易造成執行緒數迅速增加,這種情況要衡量使用該類執行緒池是否合適
3、緩衝執行
- 佇列:LinkedBlockingQueue和ArrayBlockingQueue
- 典型案例:newFixedThreadPool(int threadSize)
注意:
- 使用該類執行緒池,最好使用LinkedBlockingQueue(無界佇列),但是當大量併發任務的湧入,導致核心執行緒處理不過來,佇列元素會大量增加,可能會報記憶體溢位
- 當然,對於上邊這種情況的話,如果是ArrayBlockingQueue的話,如果設定得當,可以回絕一些任務,而不報記憶體溢位
4、執行緒數的確定
- 公式:啟動執行緒數=[任務執行時間/(任務執行時間-IO等待時間)]*CPU核數
注意:
- 如果任務大都是CPU計算型任務,啟動執行緒數=CPU核數
- 如果任務大多需要等待磁碟操作,網路響應,啟動執行緒數可以參照公式估算,當然>CPU核數
總結:
一般使用執行緒池,按照如下順序依次考慮(只有前者不滿足場景需求,才考慮後者):
newCachedThreadPool-->newFixedThreadPool(int threadSize)-->ThreadPoolExecutor
- newCachedThreadPool不需要指定任何引數
- newFixedThreadPool需要指定執行緒池數(核心執行緒數==最大執行緒數)
- ThreadPoolExecutor需要指定核心執行緒數、最大執行緒數、閒置超時時間、佇列、佇列容量,甚至還有回絕策略和執行緒工廠
對於:newFixedThreadPool和ThreadPoolExecutor的核心數可以參照上述給出的公式進行估算。