接上篇,在上篇中介紹了線程池的設(shè)計(jì)需求以及使用,在這里我們分析Concurrent包中線程池的實(shí)現(xiàn)類ThreadPoolExecutor的設(shè)計(jì),是不是感覺(jué)沒(méi)意義,人家都實(shí)現(xiàn)了還分析啥?當(dāng)然是提高我們自身的設(shè)計(jì)能力了。對(duì)于設(shè)計(jì)能力的提高,我認(rèn)為一方面我們要在具體實(shí)踐中,能夠?qū)W習(xí)前人
總結(jié)的設(shè)計(jì)思想(比如設(shè)計(jì)模式之類的),根據(jù)具體上下文,能夠融會(huì)貫通的使用他們。另一方面分析優(yōu)秀的框架設(shè)計(jì)與實(shí)現(xiàn)也是很好的方式,當(dāng)然JDK設(shè)計(jì)是最好的學(xué)習(xí)資料。閑話多了,切入主題,設(shè)計(jì)要點(diǎn):
- 縱觀在JDK1.5以前我們自己實(shí)現(xiàn)的線程池,還是Concurrent提供的線程池,在線程池中首先我們要兩個(gè)容器維護(hù) 線程池中的線程 與 提交給線程池中的Task。
- 線程池與Task如何關(guān)聯(lián),什么樣的Task才可以提交的該線程池中執(zhí)行呢。所以我們要定義一個(gè)接口,分離線程池與具體
- Task的耦合關(guān)系,ThreadPoolExecutor可以接受實(shí)現(xiàn)Runnable接口或者Callable接口(其實(shí)最后也是組裝為Runnable接口)的具體Task。
- 線程池中的線程從Task隊(duì)列中去Task執(zhí)行。
以上就是線程池設(shè)計(jì)的要點(diǎn)。
在ThreadPoolExecutor中,有一個(gè)內(nèi)部類Worker,實(shí)現(xiàn)了Runnable,也就是線程池中的線程,不言而喻,它的Run方法就是從Task隊(duì)列
取Task,調(diào)用Task的run方法(Task 是實(shí)現(xiàn)了Runnable接口的),執(zhí)行Task,依次類推,直到?jīng)]有隊(duì)列里面Task。看下圖

了解了線程的創(chuàng)建以及執(zhí)行Task的流程,下面讓我們?cè)诳纯碩hreadPoolExecutor是如何觸發(fā)創(chuàng)建線程池線程的呢? 何時(shí)啟動(dòng)線程池里的
線程執(zhí)行Task呢?再這之前,我們先說(shuō)明一下,在ThreadPoolExecutor中引入了兩個(gè)描述線程池中線程數(shù)量的屬性,corePoolSize和 maximumPoolSize
corePoolSize 初始化時(shí)線程池中線程的數(shù)量。
maximumPoolSize 線程池中的程的最大數(shù)量,當(dāng)Task無(wú)法插入Task隊(duì)列,線程池線程數(shù)量又達(dá)到maximumPoolSize時(shí),啟用Reject策略,
Reject過(guò)多的Task。
下圖說(shuō)明了當(dāng)我們創(chuàng)建一個(gè)線程池,并提交Task時(shí),ThreadPoolExecutor首先判斷是否達(dá)到corePoolSize,沒(méi)有就在創(chuàng)建一個(gè)線程,提高吞吐量。如果超過(guò)那么直接將該Task插入Task隊(duì)列。
如果插入失敗,說(shuō)明Task隊(duì)列已滿,那么嘗試是否達(dá)到maximumPoolSize,如果沒(méi)有,那么創(chuàng)建而外的線程處理改
Task,減低Task失敗率。
如果已經(jīng)達(dá)到了maximumPoolSize,對(duì)不起,只能Reject了。
這其實(shí)是線程池設(shè)計(jì)處理Task的策略。大家可以細(xì)細(xì)體會(huì),這個(gè)策略的優(yōu)勢(shì)。
到現(xiàn)在其實(shí)已經(jīng)基本說(shuō)明了ThreadPoolExecutor的設(shè)計(jì)了,其實(shí)設(shè)計(jì)思想是不是跟以前我們自個(gè)設(shè)計(jì)線程池都一樣?只是在具體實(shí)現(xiàn)上更加完善,更加完美!
對(duì)了大家如果感興趣可以看看ThreadPoolExecutor如何優(yōu)雅的Shutdown,這些設(shè)計(jì)實(shí)現(xiàn)細(xì)節(jié),都可以在我們的實(shí)踐中應(yīng)用。