線程池參數(shù)的合理設(shè)置

一:線程池參數(shù)簡介

ThreadPoolExecutor類可設(shè)置的參數(shù)主要有:
corePoolSize:核心線程
1.核心線程會(huì)一直存活甘苍,及時(shí)沒有任務(wù)需要執(zhí)行
2.當(dāng)線程數(shù)小于核心線程數(shù)時(shí)间涵,即使有線程空閑合敦,線程池也會(huì)優(yōu)先創(chuàng)建新線程處理
3.設(shè)置allowCoreThreadTimeout=true(默認(rèn)false)時(shí),核心線程會(huì)超時(shí)關(guān)閉

queueCapacity:任務(wù)隊(duì)列容量(阻塞隊(duì)列)

當(dāng)核心線程數(shù)達(dá)到最大時(shí),新任務(wù)會(huì)放在隊(duì)列中排隊(duì)等待執(zhí)行

maxPoolSize:最大線程數(shù)
1.當(dāng)線程數(shù)>=corePoolSize坐漏,且任務(wù)隊(duì)列已滿時(shí)。線程池會(huì)創(chuàng)建新線程來處理任務(wù)
2.當(dāng)線程數(shù)=maxPoolSize,且任務(wù)隊(duì)列已滿時(shí)赊琳,線程池會(huì)拒絕處理任務(wù)而拋出異常

keepAliveTime:線程空閑時(shí)間
1.當(dāng)線程空閑時(shí)間達(dá)到keepAliveTime時(shí)街夭,線程會(huì)退出,直到線程數(shù)量=corePoolSize
2.如果allowCoreThreadTimeout=true躏筏,則會(huì)直到線程數(shù)量=0

rejectedExecutionHandler:任務(wù)拒絕處理器
兩種情況會(huì)拒絕處理任務(wù):
1.當(dāng)線程數(shù)已經(jīng)達(dá)到maxPoolSize板丽,切隊(duì)列已滿,會(huì)拒絕新任務(wù)
2.當(dāng)線程池被調(diào)用shutdown()后趁尼,會(huì)等待線程池里的任務(wù)執(zhí)行完畢埃碱,再shutdown。如果在調(diào)用shutdown()和線程池真正shutdown之間提交任務(wù)酥泞,會(huì)拒絕新任務(wù)砚殿。

線程池會(huì)調(diào)用rejectedExecutionHandler來處理這個(gè)任務(wù)。如果沒有設(shè)置芝囤,默認(rèn)是AbortPolicy似炎,會(huì)拋出異常。
ThreadPoolExecutor類有幾個(gè)內(nèi)部實(shí)現(xiàn)類來處理拒絕任務(wù):
1.AbortPolicy 丟棄任務(wù)悯姊,拋運(yùn)行時(shí)異常
2.CallerRunsPolicy 執(zhí)行任務(wù)
3.DiscardPolicy 忽視羡藐,什么都不會(huì)發(fā)生
4.DiscardOldestPolicy 從隊(duì)列中踢出最先進(jìn)入隊(duì)列(最后一個(gè)執(zhí)行)的任務(wù)
5.實(shí)現(xiàn)RejectedExecutionHandler接口,可自定義處理器

二:ThreadPoolExecutor執(zhí)行順序:

1.當(dāng)線程數(shù)小于核心線程數(shù)時(shí)悯许,創(chuàng)建線程传睹。
2.當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列未滿時(shí)岸晦,將任務(wù)放入任務(wù)隊(duì)列欧啤。
3.當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列已滿
3.1若線程數(shù)小于最大線程數(shù)启上,創(chuàng)建線程
3.2若線程數(shù)等于最大線程數(shù)邢隧,拋出異常,拒絕任務(wù)

三:線程池參數(shù)的合理設(shè)置

為了說明合理設(shè)置的條件冈在,我們首先確定有以下幾個(gè)相關(guān)參數(shù):
1.tasks倒慧,程序每秒需要處理的最大任務(wù)數(shù)量(假設(shè)系統(tǒng)每秒任務(wù)數(shù)為100~1000)
2.tasktime,單線程處理一個(gè)任務(wù)所需要的時(shí)間(每個(gè)任務(wù)耗時(shí)0.1秒)
3.responsetime包券,系統(tǒng)允許任務(wù)最大的響應(yīng)時(shí)間(每個(gè)任務(wù)的響應(yīng)時(shí)間不得超過2秒)

corePoolSize

每個(gè)任務(wù)需要tasktime秒處理纫谅,則每個(gè)線程每秒可處理1/tasktime個(gè)任務(wù)。系統(tǒng)每秒有tasks個(gè)任務(wù)需要處理溅固,則需要的線程數(shù)為:tasks/(1/tasktime)付秕。
即tasks*tasktime個(gè)線程數(shù)。假設(shè)系統(tǒng)每秒任務(wù)數(shù)為100到1000之間侍郭,每個(gè)任務(wù)耗時(shí)0.1秒询吴,則需要100x0.1至1000x0.1掠河,即10到100個(gè)線程。那么corePoolSize應(yīng)該設(shè)置為大于10猛计。
具體數(shù)字最好根據(jù)8020原則唠摹,即80%情況下系統(tǒng)每秒任務(wù)數(shù),若系統(tǒng)80%的情況下任務(wù)數(shù)小于200奉瘤,最多時(shí)為1000勾拉,則corePoolSize可設(shè)置為20

queueCapacity:任務(wù)隊(duì)列的長度

任務(wù)隊(duì)列的長度要根據(jù)核心線程數(shù)盗温,以及系統(tǒng)對(duì)任務(wù)響應(yīng)時(shí)間的要求有關(guān)望艺。隊(duì)列長度可以設(shè)置為(corePoolSize/tasktime)responsetime: (20/0.1)2=400,即隊(duì)列長度可設(shè)置為400肌访。
如果隊(duì)列長度設(shè)置過大找默,會(huì)導(dǎo)致任務(wù)響應(yīng)時(shí)間過長,如以下寫法:
LinkedBlockingQueue queue = new LinkedBlockingQueue();
這實(shí)際上是將隊(duì)列長度設(shè)置為Integer.MAX_VALUE吼驶,將會(huì)導(dǎo)致線程數(shù)量永遠(yuǎn)為corePoolSize惩激,再也不會(huì)增加,當(dāng)任務(wù)數(shù)量陡增時(shí)蟹演,任務(wù)響應(yīng)時(shí)間也將隨之陡增风钻。

maxPoolSize:最大線程數(shù)

當(dāng)系統(tǒng)負(fù)載達(dá)到最大值時(shí),核心線程數(shù)已無法按時(shí)處理完所有任務(wù)酒请,這時(shí)就需要增加線程骡技。每秒200個(gè)任務(wù)需要20個(gè)線程,那么當(dāng)每秒達(dá)到1000個(gè)任務(wù)時(shí)羞反,則需要(1000-queueCapacity)*(20/200)布朦,即60個(gè)線程,可將maxPoolSize設(shè)置為60昼窗。

keepAliveTime:

線程數(shù)量只增加不減少也不行是趴。當(dāng)負(fù)載降低時(shí),可減少線程數(shù)量澄惊,如果一個(gè)線程空閑時(shí)間達(dá)到keepAliveTiime唆途,該線程就退出。默認(rèn)情況下線程池最少會(huì)保持corePoolSize個(gè)線程掸驱。keepAliveTiime設(shè)定值可根據(jù)任務(wù)峰值持續(xù)時(shí)間來設(shè)定肛搬。

以上關(guān)于線程數(shù)量的計(jì)算并沒有考慮CPU的情況。若結(jié)合CPU的情況毕贼,比如温赔,當(dāng)線程數(shù)量達(dá)到50時(shí),CPU達(dá)到100%帅刀,則將maxPoolSize設(shè)置為60也不合適让腹,此時(shí)若系統(tǒng)負(fù)載長時(shí)間維持在每秒1000個(gè)任務(wù),則超出線程池處理能力扣溺,應(yīng)設(shè)法降低每個(gè)任務(wù)的處理時(shí)間(tasktime)。

ps:

該文章創(chuàng)作原因來源于阿里java后端面試:
如果給你8G內(nèi)存,500G固態(tài)硬盤譬圣,雙CPU四核的配置源葫,現(xiàn)在有100個(gè)用戶訪問你的系統(tǒng),請(qǐng)你設(shè)計(jì)一下你剛剛說的那些線程池參數(shù)驱犹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嘲恍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子雄驹,更是在濱河造成了極大的恐慌佃牛,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件医舆,死亡現(xiàn)場離奇詭異俘侠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蔬将,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門爷速,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人霞怀,你說我怎么就攤上這事惫东。” “怎么了毙石?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵廉沮,是天一觀的道長。 經(jīng)常有香客問我徐矩,道長废封,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任丧蘸,我火速辦了婚禮漂洋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘力喷。我一直安慰自己刽漂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布弟孟。 她就那樣靜靜地躺著贝咙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拂募。 梳的紋絲不亂的頭發(fā)上庭猩,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天窟她,我揣著相機(jī)與錄音,去河邊找鬼蔼水。 笑死震糖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的趴腋。 我是一名探鬼主播吊说,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼优炬!你這毒婦竟也來了颁井?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤蠢护,失蹤者是張志新(化名)和其女友劉穎雅宾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葵硕,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秀又,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贬芥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吐辙。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蘸劈,靈堂內(nèi)的尸體忽然破棺而出昏苏,到底是詐尸還是另有隱情,我是刑警寧澤威沫,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布贤惯,位于F島的核電站,受9級(jí)特大地震影響棒掠,放射性物質(zhì)發(fā)生泄漏孵构。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一烟很、第九天 我趴在偏房一處隱蔽的房頂上張望颈墅。 院中可真熱鬧,春花似錦雾袱、人聲如沸恤筛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毒坛。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間煎殷,已是汗流浹背屯伞。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留豪直,地道東北人劣摇。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像顶伞,于是被迫代替她去往敵國和親饵撑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子剑梳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350