圖16 動(dòng)態(tài)修改線程池參數(shù)新舊流程對(duì)比
基于以上三個(gè)方向?qū)Ρ?nbsp;, 我們可以看出參數(shù)動(dòng)態(tài)化方向簡(jiǎn)單有效 。
3.3 動(dòng)態(tài)化線程池
3.3.1 整體設(shè)計(jì)
動(dòng)態(tài)化線程池的核心設(shè)計(jì)包括以下三個(gè)方面:
- 簡(jiǎn)化線程池配置:線程池構(gòu)造參數(shù)有8個(gè) , 但是最核心的是3個(gè):corePoolSize、maximumPoolSize , workQueue , 它們最大程度地決定了線程池的任務(wù)分配和線程分配策略 。考慮到在實(shí)際應(yīng)用中我們獲取并發(fā)性的場(chǎng)景主要是兩種:(1)并行執(zhí)行子任務(wù) , 提高響應(yīng)速度 。這種情況下 , 應(yīng)該使用同步隊(duì)列 , 沒(méi)有什么任務(wù)應(yīng)該被緩存下來(lái) , 而是應(yīng)該立即執(zhí)行 。(2)并行執(zhí)行大批次任務(wù) , 提升吞吐量 。這種情況下 , 應(yīng)該使用有界隊(duì)列 , 使用隊(duì)列去緩沖大批量的任務(wù) , 隊(duì)列容量必須聲明 , 防止任務(wù)無(wú)限制堆積 。所以線程池只需要提供這三個(gè)關(guān)鍵參數(shù)的配置 , 并且提供兩種隊(duì)列的選擇 , 就可以滿足絕大多數(shù)的業(yè)務(wù)需求 , Less is More 。
- 參數(shù)可動(dòng)態(tài)修改:為了解決參數(shù)不好配 , 修改參數(shù)成本高等問(wèn)題 。在Java線程池留有高擴(kuò)展性的基礎(chǔ)上 , 封裝線程池 , 允許線程池監(jiān)聽(tīng)同步外部的消息 , 根據(jù)消息進(jìn)行修改配置 。將線程池的配置放置在平臺(tái)側(cè) , 允許開發(fā)同學(xué)簡(jiǎn)單的查看、修改線程池配置 。
- 增加線程池監(jiān)控:對(duì)某事物缺乏狀態(tài)的觀測(cè) , 就對(duì)其改進(jìn)無(wú)從下手 。在線程池執(zhí)行任務(wù)的生命周期添加監(jiān)控能力 , 幫助開發(fā)同學(xué)了解線程池狀態(tài) 。

圖17 動(dòng)態(tài)化線程池整體設(shè)計(jì)
3.3.2 功能架構(gòu)
動(dòng)態(tài)化線程池提供如下功能:
- 動(dòng)態(tài)調(diào)參:支持線程池參數(shù)動(dòng)態(tài)調(diào)整、界面化操作;包括修改線程池核心大小、最大核心大小、隊(duì)列長(zhǎng)度等;參數(shù)修改后及時(shí)生效 。
- 任務(wù)監(jiān)控:支持應(yīng)用粒度、線程池粒度、任務(wù)粒度的Transaction監(jiān)控;可以看到線程池的任務(wù)執(zhí)行情況、最大任務(wù)執(zhí)行時(shí)間、平均任務(wù)執(zhí)行時(shí)間、95/99線等 。
- 負(fù)載告警:線程池隊(duì)列任務(wù)積壓到一定值的時(shí)候會(huì)通過(guò)大象(美團(tuán)內(nèi)部通訊工具)告知應(yīng)用開發(fā)負(fù)責(zé)人;當(dāng)線程池負(fù)載數(shù)達(dá)到一定閾值的時(shí)候會(huì)通過(guò)大象告知應(yīng)用開發(fā)負(fù)責(zé)人 。
- 操作監(jiān)控:創(chuàng)建/修改和刪除線程池都會(huì)通知到應(yīng)用的開發(fā)負(fù)責(zé)人 。
- 操作日志:可以查看線程池參數(shù)的修改記錄 , 誰(shuí)在什么時(shí)候修改了線程池參數(shù)、修改前的參數(shù)值是什么 。
- 權(quán)限校驗(yàn):只有應(yīng)用開發(fā)負(fù)責(zé)人才能夠修改應(yīng)用的線程池參數(shù) 。

圖18 動(dòng)態(tài)化線程池功能架構(gòu)
參數(shù)動(dòng)態(tài)化
JDK原生線程池ThreadPoolExecutor提供了如下幾個(gè)public的setter方法 , 如下圖所示:

圖19 JDK 線程池參數(shù)設(shè)置接口
JDK允許線程池使用方通過(guò)ThreadPoolExecutor的實(shí)例來(lái)動(dòng)態(tài)設(shè)置線程池的核心策略 , 以setCorePoolSize為方法例 , 在運(yùn)行期線程池使用方調(diào)用此方法設(shè)置corePoolSize之后 , 線程池會(huì)直接覆蓋原來(lái)的corePoolSize值 , 并且基于當(dāng)前值和原始值的比較結(jié)果采取不同的處理策略 。對(duì)于當(dāng)前值小于當(dāng)前工作線程數(shù)的情況 , 說(shuō)明有多余的worker線程 , 此時(shí)會(huì)向當(dāng)前idle的worker線程發(fā)起中斷請(qǐng)求以實(shí)現(xiàn)回收 , 多余的worker在下次idle的時(shí)候也會(huì)被回收;對(duì)于當(dāng)前值大于原始值且當(dāng)前隊(duì)列中有待執(zhí)行任務(wù) , 則線程池會(huì)創(chuàng)建新的worker線程來(lái)執(zhí)行隊(duì)列任務(wù) , setCorePoolSize具體流程如下:
推薦閱讀
- cad卸載工具怎么用 cad卸載干凈的教程
- qq營(yíng)銷工具源碼 最有效推廣的方式
- 目前三防手機(jī)哪個(gè)好 最好的三防手機(jī)品牌
- 哪些人不宜喝酒
- 艾灸真的可以治療哮喘嗎
- 面包硬的其他原因
- 釣鱸魚的餌料比較好用的有哪些
- 黃皮果的食用方法
- 骨盆前傾該怎么練呢
- 骨盆前傾是怎么形成的呢
