(1)高并發、任務執行時間短的業務,線程池線程數可以設置為CPU核數+1,減少線程上下文的切換
(2)并發不高、任務執行時間長的業務要區分開看:
? ? ? ?a)假如是業務時間長集中在IO操作上,也就是IO密集型的任務,因為IO操作并不占用CPU,所以不要讓所有的CPU閑下來,可以加大線程池中的線程數目,讓CPU處理更多的業務
? ? ? ?b)假如是業務時間長集中在計算操作上,也就是計算密集型任務,這個就沒辦法了,和(1)一樣吧,線程池中的線程數設置得少一些,減少線程上下文的切換
(3)并發高、業務執行時間長,解決這種類型任務的關鍵不在于線程池而在于整體架構的設計,看看這些業務里面某些數據是否能做緩存是第一步,增加服務器是第二步,至于線程池的設置,設置參考(2)。最后,業務執行時間長的問題,也可能需要分析一下,看看能不能使用中間件對任務進行拆分和解耦
?
如何來設置
? ? ?需要根據幾個值來決定
? ? ?? ? ?tasks :每秒的任務數,假設為500~1000
? ? ?? ? ?taskcost:每個任務花費時間,假設為0.1s
? ? ?? ? ?responsetime:系統允許容忍的最大響應時間,假設為1s
? ? ?做幾個計算
? ? ?? ? ?corePoolSize = 每秒需要多少個線程處理??
? ? ? ? ? ? ? ?threadcount = tasks/(1/taskcost) =tasks*taskcout = ?(500~1000)*0.1 = 50~100 個線程。corePoolSize設置應該大于50
? ? ?? ? ?? ? ?根據8020原則,如果80%的每秒任務數小于800,那么corePoolSize設置為80即可
? ? ?? ? ?queueCapacity = (coreSizePool/taskcost)*responsetime
? ? ?? ? ?? ? ?計算可得 queueCapacity = 80/0.1*1 = 80。意思是隊列里的線程可以等待1s,超過了的需要新開線程來執行
? ? ?? ? ?? ? ?切記不能設置為Integer.MAX_VALUE,這樣隊列會很大,線程數只會保持在corePoolSize大小,當任務陡增時,不能新開線程來執行,響應時間會隨之陡增。
? ? ?? ? ?maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost)(最大任務數-隊列容量)/每個線程每秒處理能力 = 最大線程數
? ? ?? ? ?? ? ? 計算可得 maxPoolSize = (1000-80)/10 = 92
? ? ?? ? ?rejectedExecutionHandler:根據具體情況來決定,任務不重要可丟棄,任務重要則要利用一些緩沖機制來處理
? ? ?? ? ?keepAliveTime和allowCoreThreadTimeout:采用默認通常能滿足