續(xù)上篇所述,Java線程池作為jdk組件箱中重要的一員,其產(chǎn)生的背后是要來(lái)解決一些需求,如線程的管理,任務(wù)的管理,自身的生命周期的管理等。
有了需求,就有了一張藍(lán)圖,其描繪了程序最初的樣子,程序設(shè)計(jì)由此便有了依據(jù)。按照古老的 “程序 =?數(shù)據(jù)結(jié)構(gòu)+?算法”?的指揮思想,我們首先得確定線程池的數(shù)據(jù)結(jié)構(gòu)。而數(shù)據(jù)結(jié)構(gòu)說(shuō)白就是數(shù)據(jù)的組織與存儲(chǔ)的方式,就像是好的倉(cāng)庫(kù)管理員對(duì)貨物分門(mén)別類(lèi)的放置一樣,我們需要對(duì)線程池所管理的數(shù)據(jù)的進(jìn)行妥當(dāng)?shù)陌仓谩?/p>
首先,我們先明確線程池所管理的核心數(shù)據(jù)有哪些:一組線程及其描述量,一組任務(wù)及其描述量以及自身的狀態(tài)量(描述自身生命周期)。
我們先講一組線程及其描述量,線程池要持有一組線程的所有引用,這些線程得在線程池里創(chuàng)建,但創(chuàng)建的數(shù)量應(yīng)該有一個(gè)上限,不能無(wú)限創(chuàng)建,故我們需要一個(gè)描述量maximumPoolSize來(lái)描述線程池能承受的實(shí)際最大線程數(shù),另外,為了進(jìn)一步細(xì)粒度地約束線程池的大小,避免過(guò)多的線程空轉(zhuǎn)閑置,線程池需要另一個(gè)描述量corePoolSize來(lái)描述久住線程池的最小線程數(shù)。綜上,線程池需要一個(gè)容器,三個(gè)描述量來(lái)封裝線程的相關(guān)操作。
接著我們來(lái)講一組任務(wù)及其描述量,線程池作為任務(wù)的調(diào)度和分配者,當(dāng)任務(wù)過(guò)多時(shí),需要一個(gè)任務(wù)的緩沖區(qū)來(lái)暫存待執(zhí)行的任務(wù),為了了解任務(wù)完成的總體情況,需要一個(gè)描述量completedTaskCount來(lái)描述當(dāng)前線程池的完成的任務(wù)總數(shù),綜上,線程池需要另外一個(gè)容器,一個(gè)描述量來(lái)封裝任務(wù)的相關(guān)操作。
最后,我們講線程池自身的狀態(tài)量,線程池是一個(gè)獨(dú)立的組件,組件內(nèi)部對(duì)調(diào)用者來(lái)說(shuō)是黑盒,雖說(shuō)是黑盒,也要有一些必要的信息暴露給調(diào)用者,以便調(diào)用者了解并根據(jù)這些信息做出對(duì)應(yīng)的決策。這里就包括RUNNING(正在運(yùn)行),SHUTDOWN(關(guān)閉),STOP(停止),TIDYING(清理),TERMINATED(結(jié)束)五種狀態(tài),那為什么需要這五種狀態(tài),這里就需要聯(lián)系線程池的優(yōu)雅停止處理的考慮,多出來(lái)的SHUTDOWN(關(guān)閉),STOP(停止),TIDYING(清理)三種中間狀態(tài)能夠更加具體的描述線程池所處的階段。(后續(xù)會(huì)對(duì)其擴(kuò)展講)。
至此,我描述完了線程池的數(shù)據(jù)結(jié)構(gòu),打個(gè)比方作為結(jié)束:想像線程池是一個(gè)實(shí)體的工廠,線程是工廠的員工,任務(wù)是工廠的加工的原料。員工需要工位(容器),員工有正式員工和非正式員工(外包或者臨時(shí)工),正式員工有corePoolSize人,工廠員工有maximumPoolSize人;原料需要倉(cāng)庫(kù)來(lái)暫存(容器),completedTaskCount描述了原料的消耗量。工廠也有開(kāi)工,沒(méi)工開(kāi),破產(chǎn)清理,倒閉等不同的狀態(tài)。
希望上訴比喻能增強(qiáng)對(duì)線程池?cái)?shù)據(jù)結(jié)構(gòu)的理解。下一篇我們講:
《java線程池算法》