在線程池的使用過程中膛壹,他的核心參數(shù)配置一直是一個(gè)很讓人頭疼的問題脆炎。
在《美團(tuán)Java線程池原理及其在美團(tuán)業(yè)務(wù)中的實(shí)踐》中,我找到了這張圖效五。
經(jīng)過美團(tuán)技術(shù)人員的調(diào)研噩茄,發(fā)現(xiàn)并不能得出一個(gè)通用的線程池計(jì)算方式。并發(fā)任務(wù)的執(zhí)行情況和任務(wù)類型相關(guān)续徽,IO密集型和CPU密集型的任務(wù)運(yùn)行起來的情況差異非常大蚓曼,但這種占比是較難合理預(yù)估的,這導(dǎo)致很難有一個(gè)簡(jiǎn)單有效的通用公式幫我們直接計(jì)算出結(jié)果钦扭。
盡管經(jīng)過謹(jǐn)慎的評(píng)估纫版,仍然不能夠保證一次計(jì)算出來合適的參數(shù),那么我們是否可以將修改線程池參數(shù)的成本降下來土全,這樣至少可以發(fā)生故障的時(shí)候可以快速調(diào)整從而縮短故障恢復(fù)的時(shí)間呢捎琐?
于是乎,我基于《美團(tuán)Java線程池原理及其在美團(tuán)業(yè)務(wù)中的實(shí)踐》里的思路實(shí)現(xiàn)了一個(gè)簡(jiǎn)易的線程池動(dòng)態(tài)配置的實(shí)現(xiàn)demo裹匙。
這是我的代碼gitee的地址:dynamic-thread-pool-demo
1.找到線程池中設(shè)置 核心參數(shù) corePoolSize(核心線程數(shù))瑞凑、maximumPoolSize(最大線程數(shù))、queueCapacity(阻塞隊(duì)列長(zhǎng)度)的方法概页。經(jīng)過源碼閱讀籽御,發(fā)現(xiàn)
但是又發(fā)現(xiàn)阻塞隊(duì)列的capacity屬性是final修飾的,也就是不可修改的惰匙。咱們?cè)撊绾涡薷腸apacity的大小呢技掏?
2.重寫一個(gè)新的LinkedBlockingQueue命名為MyLinkedBlockingQueue,將LinkedBlockingQueue代碼遷移過來项鬼,然后將capacity的final修飾去除哑梳,同時(shí)實(shí)現(xiàn)它的set,get方法绘盟。
3.新建一個(gè)DynamicThreadPoolDemo類鸠真,新建一個(gè)創(chuàng)建自定義線程池的方法悯仙,阻塞線程池用MyLinkedBlockingQueue
4.為了驗(yàn)證動(dòng)態(tài)調(diào)整參數(shù)是否有效,咱們先建一個(gè)枚舉吠卷,用來表示線程池的狀態(tài)
5.創(chuàng)建 printExecutorInfo方法锡垄,打印一下當(dāng)前線程池的信息數(shù)據(jù)
6.創(chuàng)建main方法來驗(yàn)證動(dòng)態(tài)調(diào)參。
7.如何驗(yàn)證祭隔?如果不改變參數(shù)的情況下货岭,15個(gè)任務(wù),最大線程數(shù)為5疾渴,那么運(yùn)行時(shí)間大概是30s左右千贯。改變參數(shù)之后,最大線程數(shù)為10個(gè)程奠,那么15個(gè)任務(wù)只需要20s就可以全部完成
8.運(yùn)行程序丈牢,查看控制臺(tái),驗(yàn)證結(jié)果
9.經(jīng)過程序的驗(yàn)證發(fā)現(xiàn)動(dòng)態(tài)調(diào)參是可行的瞄沙。在咱們實(shí)際生產(chǎn)環(huán)境中該如何落地呢己沛?可以考慮在配置中心(例如Apollo)上進(jìn)行調(diào)參