接著上一篇探討線程池留下的尾巴,,如何合理的設置線程池大小,。
要想合理的配置線程池的大小,首先得分析任務的特性,,可以從以下幾個角度分析:
- 任務的性質:CPU密集型任務,、IO密集型任務、混合型任務,。
- 任務的優(yōu)先級:高,、中、低,。
- 任務的執(zhí)行時間:長,、中、短,。
- 任務的依賴性:是否依賴其他系統(tǒng)資源,,如數據庫連接等。
性質不同的任務可以交給不同規(guī)模的線程池執(zhí)行,。
對于不同性質的任務來說,,CPU密集型任務應配置盡可能小的線程,,如配置CPU個數+1的線程數,IO密集型任務應配置盡可能多的線程,,因為IO操作不占用CPU,,不要讓CPU閑下來,應加大線程數量,,如配置兩倍CPU個數+1,,而對于混合型的任務,如果可以拆分,,拆分成IO密集型和CPU密集型分別處理,,前提是兩者運行的時間是差不多的,如果處理時間相差很大,,則沒必要拆分了,。
若任務對其他系統(tǒng)資源有依賴,如某個任務依賴數據庫的連接返回的結果,,這時候等待的時間越長,,則CPU空閑的時間越長,那么線程數量應設置得越大,,才能更好的利用CPU,。
當然具體合理線程池值大小,需要結合系統(tǒng)實際情況,,在大量的嘗試下比較才能得出,,以上只是前人總結的規(guī)律。
在這篇如何合理地估算線程池大???文章中發(fā)現了一個估算合理值的公式
最佳線程數目 = ((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數目
比如平均每個線程CPU運行時間為0.5s,而線程等待時間(非CPU運行時間,,比如IO)為1.5s,,CPU核心數為8,那么根據上面這個公式估算得到:((0.5+1.5)/0.5)*8=32,。這個公式進一步轉化為:
最佳線程數目 = (線程等待時間與線程CPU時間之比 + 1)* CPU數目
可以得出一個結論:
線程等待時間所占比例越高,,需要越多線程。線程CPU時間所占比例越高,,需要越少線程,。
以上公式與之前的CPU和IO密集型任務設置線程數基本吻合。
并發(fā)編程網上的一個問題
高并發(fā),、任務執(zhí)行時間短的業(yè)務怎樣使用線程池,?并發(fā)不高、任務執(zhí)行時間長的業(yè)務怎樣使用線程池,?并發(fā)高,、業(yè)務執(zhí)行時間長的業(yè)務怎樣使用線程池?
(1)高并發(fā),、任務執(zhí)行時間短的業(yè)務,,線程池線程數可以設置為CPU核數+1,減少線程上下文的切換
(2)并發(fā)不高,、任務執(zhí)行時間長的業(yè)務要區(qū)分開看:
a)假如是業(yè)務時間長集中在IO操作上,,也就是IO密集型的任務,因為IO操作并不占用CPU,,所以不要讓所有的CPU閑下來,,可以適當加大線程池中的線程數目,讓CPU處理更多的業(yè)務
b)假如是業(yè)務時間長集中在計算操作上,,也就是計算密集型任務,,這個就沒辦法了,和(1)一樣吧,,線程池中的線程數設置得少一些,,減少線程上下文的切換
(3)并發(fā)高、業(yè)務執(zhí)行時間長,,解決這種類型任務的關鍵不在于線程池而在于整體架構的設計,,看看這些業(yè)務里面某些數據是否能做緩存是第一步,增加服務器是第二步,,至于線程池的設置,,設置參考(2)。最后,,業(yè)務執(zhí)行時間長的問題,,也可能需要分析一下,看看能不能使用中間件對任務進行拆分和解耦,。
|