Java線程池參數詳解

JDK1.5中引入了強大的concurrent包,其中最經常使用的莫過了線程池的實現ThreadPoolExecutor,它給咱們帶來了極大的方便,但同時,對於該線程池不恰當的設置也可能使其效率並不能達到預期的效果,甚至僅至關於或低於單線程的效率。線程

ThreadPoolExecutor類可設置的參數主要有:隊列

 

  • corePoolSize

 

核心線程數,核心線程會一直存活,即便沒有任務須要處理。當線程數小於核心線程數時,即便現有的線程空閒,線程池也會優先建立新線程來處理任務,而不是直接交給現有的線程處理。ci

核心線程在allowCoreThreadTimeout被設置爲true時會超時退出,默認狀況下不會退出。it

 

  • maxPoolSize
當線程數大於或等於核心線程,且任務隊列已滿時,線程池會建立新的線程,直到線程數量達到maxPoolSize。若是線程數已等於maxPoolSize,且任務隊列已滿,則已超出線程池的處理能力,線程池會拒絕處理任務而拋出異常。

 

  • keepAliveTime

 

當線程空閒時間達到keepAliveTime,該線程會退出,直到線程數量等於corePoolSize。若是allowCoreThreadTimeout設置爲true,則全部線程均會退出直到線程數量爲0。效率

 

  • allowCoreThreadTimeout

是否容許核心線程空閒退出,默認值爲false。線程池

  • queueCapacity

任務隊列容量。從maxPoolSize的描述上能夠看出,任務隊列的容量會影響到線程的變化,所以任務隊列的長度也須要恰當的設置。queue

 

線程池按如下行爲執行任務im

 

  1. 當線程數小於核心線程數時,建立線程。
  2. 當線程數大於等於核心線程數,且任務隊列未滿時,將任務放入任務隊列。
  3. 當線程數大於等於核心線程數,且任務隊列已滿
    1. 若線程數小於最大線程數,建立線程
    2. 若線程數等於最大線程數,拋出異常,拒絕任務

 

 

系統負載異常

參數的設置跟系統的負載有直接的關係,下面爲系統負載的相關參數:時間

 

  • tasks,每秒須要處理的最大任務數量
  • tasktime,處理第個任務所須要的時間
  • responsetime,系統容許任務最大的響應時間,好比每一個任務的響應時間不得超過2秒。

 

 

參數設置

 

corePoolSize:

每一個任務須要tasktime秒處理,則每一個線程每鈔可處理1/tasktime個任務。系統每秒有tasks個任務須要處理,則須要的線程數爲:tasks/(1/tasktime),即tasks*tasktime個線程數。假設系統每秒任務數爲100~1000,每一個任務耗時0.1秒,則須要100*0.1至1000*0.1,即10~100個線程。那麼corePoolSize應該設置爲大於10,具體數字最好根據8020原則,即80%狀況下系統每秒任務數,若系統80%的狀況下第秒任務數小於200,最多時爲1000,則corePoolSize可設置爲20。

 

queueCapacity:

任務隊列的長度要根據核心線程數,以及系統對任務響應時間的要求有關。隊列長度能夠設置爲(corePoolSize/tasktime)*responsetime: (20/0.1)*2=400,即隊列長度可設置爲400。

隊列長度設置過大,會致使任務響應時間過長,切忌如下寫法:

LinkedBlockingQueue queue = new LinkedBlockingQueue();

這其實是將隊列長度設置爲Integer.MAX_VALUE,將會致使線程數量永遠爲corePoolSize,不再會增長,當任務數量陡增時,任務響應時間也將隨之陡增。

 

maxPoolSize:

當系統負載達到最大值時,核心線程數已沒法按時處理完全部任務,這時就須要增長線程。每秒200個任務須要20個線程,那麼當每秒達到1000個任務時,則須要(1000-queueCapacity)*(20/200),即60個線程,可將maxPoolSize設置爲60。

 

keepAliveTime:

線程數量只增長不減小也不行。當負載下降時,可減小線程數量,若是一個線程空閒時間達到keepAliveTiime,該線程就退出。默認狀況下線程池最少會保持corePoolSize個線程。

 

allowCoreThreadTimeout:

默認狀況下核心線程不會退出,可經過將該參數設置爲true,讓核心線程也退出。

 

以上關於線程數量的計算並無考慮CPU的狀況。若結合CPU的狀況,好比,當線程數量達到50時,CPU達到100%,則將maxPoolSize設置爲60也不合適,此時若系統負載長時間維持在每秒1000個任務,則超出線程池處理能力,應設法下降每一個任務的處理時間(tasktime)。

相關文章
相關標籤/搜索