1. 程式人生 > >執行緒池的選用與執行緒數的指定

執行緒池的選用與執行緒數的指定

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的核心數可以參照上述給出的公式進行估算。