線程池ThreadPoolExecutor的簡(jiǎn)單理解

(看漢字即可,圖片是源碼,可以選擇性觀看。)~

什么是線程池

線程池就是一個(gè)裝線程的集合。

用官方語(yǔ)言解釋:

線程池是一種多線程處理形式,處理過(guò)程中將任務(wù)添加到隊(duì)列,然后在創(chuàng)建線程后自動(dòng)啟動(dòng)這些任務(wù)。


為什么要用線程池

1.創(chuàng)建和銷毀線程需要時(shí)間,使用線程池,讓一個(gè)線程處理多個(gè)任務(wù),這樣創(chuàng)建和銷毀線程的時(shí)間分配到多個(gè)任務(wù)上就可以提高系統(tǒng)性能。

2.線程池可以控制線程數(shù)量,避免了每有一個(gè)任務(wù)創(chuàng)建一個(gè)線程而導(dǎo)致資源不足的尷尬

3.使用線程池可以更好的管理線程,線程池可以提供定時(shí)、定期、單線程、并發(fā)數(shù)控制等功能。


參數(shù)

我們可以通過(guò)設(shè)定不同的參數(shù),創(chuàng)建自己想要的線程池,只有七個(gè)參數(shù)

1.@param corepoolsize要保留在池中的線程數(shù)(核心線程數(shù)),即使他們是空閑的,也會(huì)保留??????????????????????????????? 如果設(shè)置@code allowcorethreadTimeout)為true,就和非核心線程的空閑時(shí)間一樣

2.@param maximumpoolsize允許的最大線程數(shù)(線程數(shù)=核心線程+非核心線程)

3.@param keepAliveTime非核心線程在空閑狀態(tài)存在的時(shí)間

4.@param unit? 是 keepalivetime參數(shù)的時(shí)間單位

5.@param workqueue用于保存任務(wù)的隊(duì)列(下面會(huì)詳細(xì)介紹隊(duì)列)

6.@參數(shù)threadfactory執(zhí)行器時(shí)要使用的工廠創(chuàng)建新線程

7.@param handler因?yàn)檫_(dá)到了線程邊界和隊(duì)列容量,程序執(zhí)行被阻止時(shí)要使用的處理程序

構(gòu)造方法

看完這七個(gè)參數(shù),在來(lái)看看jdk提供的線程池的構(gòu)造方法就簡(jiǎn)單多了(就四個(gè))

常用線程池

jdk除了提供不同的夠造方法,還提供了默認(rèn)的線程池(名字不同,參數(shù)不同,有一些參數(shù)默認(rèn)給值了)

FixedThreadPool:定長(zhǎng)的線程池,可以控制線程的數(shù)量(常用)

CachedThreadPool:緩存的線程池

線程數(shù)量無(wú)限制,線程執(zhí)行完任務(wù)有一定空閑時(shí)間,在空閑時(shí)間內(nèi),當(dāng)有任務(wù)的時(shí)候,執(zhí)行任務(wù),超過(guò)時(shí)間銷毀線程。如果沒(méi)有空閑線程,則新建線程

SingleThreadExecutor:?jiǎn)我痪€程池

只有一個(gè)線程工作,所有任務(wù)按順序執(zhí)行

ScheduledThreadPool:定長(zhǎng)的線程池

可以延遲,定期執(zhí)行任務(wù)的線程池

前面的四種都是對(duì)ThreadPoolExecutor的擴(kuò)展

ForkJoinPool :合并分支線程池

默認(rèn)都是 1 個(gè)線程。根據(jù)任務(wù)自動(dòng)的分支新的子線程。 當(dāng)子線程任務(wù)結(jié)束后,自動(dòng)合并。(科學(xué)運(yùn)輸,數(shù)據(jù)分析)

WorkStealingPool:工作竊取線程池(合并分支線程池的拓展)

能夠合理的使用CPU進(jìn)行對(duì)任務(wù)操作(并行操作),所以適合使用在很耗時(shí)的任務(wù)中

線程池的狀態(tài)

1、RUNNING線程池創(chuàng)建完以后處于這個(gè)狀態(tài),這個(gè)狀態(tài)下能接收并處理任務(wù)

2、 SHUTDOWN處于這個(gè)狀態(tài)時(shí),不接收新的任務(wù),但能處理之前沒(méi)完成的任務(wù)(調(diào)用shutdown()方法時(shí))

3、STOP處于這個(gè)狀態(tài)時(shí)不接收新任務(wù),不處理已添加業(yè)務(wù),并中斷當(dāng)前業(yè)務(wù)(調(diào)用shutdownNow()方法時(shí))

4、TIDYING處于這個(gè)狀態(tài)時(shí),線程池中任務(wù)數(shù)為0的時(shí)候

5、 TERMINATED處于這個(gè)狀態(tài)時(shí)線程池徹底終止

常用隊(duì)列

當(dāng)核心線程數(shù)最大的時(shí)候,不會(huì)創(chuàng)建線程,會(huì)把新來(lái)的任務(wù)放入隊(duì)列,當(dāng)所有的核心線程都在工作時(shí),新添加的任務(wù)會(huì)被添加到這個(gè)隊(duì)列中等待處理,如果隊(duì)列滿了,則新建非核心線程執(zhí)行任務(wù)

下面來(lái)介紹幾種隊(duì)列隊(duì)列

SynchronousQueue:緩存的線程池用的就是這個(gè)隊(duì)列。這個(gè)隊(duì)列接收到任務(wù)的時(shí)候,會(huì)直接提交給線程處理,而不保留它,如果所有線程都在工作怎么辦?那就新建一個(gè)線程來(lái)處理這個(gè)任務(wù)!所以為了保證不出現(xiàn)<線程數(shù)達(dá)到了maximumPoolSize而不能新建線程>的錯(cuò)誤,使用這個(gè)類型隊(duì)列的時(shí)候,maximumPoolSize一般指定成Integer.MAX_VALUE,即無(wú)限大

LinkedBlockingQueue:定長(zhǎng)線程池用的是這個(gè)隊(duì)列。這個(gè)隊(duì)列接收到任務(wù)的時(shí)候,如果當(dāng)前線程數(shù)小于核心線程數(shù),則新建線程(核心線程)處理任務(wù);如果當(dāng)前線程數(shù)等于核心線程數(shù),則進(jìn)入隊(duì)列等待。由于這個(gè)隊(duì)列沒(méi)有最大值限制,即所有超過(guò)核心線程數(shù)的任務(wù)都將被添加到隊(duì)列中,這也就導(dǎo)致了maximumPoolSize的設(shè)定失效,因?yàn)榭偩€程數(shù)永遠(yuǎn)不會(huì)超過(guò)corePoolSize

ArrayBlockingQueue:可以限定隊(duì)列的長(zhǎng)度,接收到任務(wù)的時(shí)候,如果沒(méi)有達(dá)到corePoolSize的值,則新建線程(核心線程)執(zhí)行任務(wù),如果達(dá)到了,則入隊(duì)等候,如果隊(duì)列已滿,則新建線程(非核心線程)執(zhí)行任務(wù),又如果總線程數(shù)到了maximumPoolSize,并且隊(duì)列也滿了,則發(fā)生錯(cuò)誤

DelayQueue:可以定期執(zhí)行任務(wù)的線程池用的就是這個(gè)隊(duì)列(ScheduledThreadPool ),隊(duì)列內(nèi)元素必須實(shí)現(xiàn)Delayed接口,這就意味著你傳進(jìn)去的任務(wù)必須先實(shí)現(xiàn)Delayed接口。這個(gè)隊(duì)列接收到任務(wù)時(shí),首先先入隊(duì),只有達(dá)到了指定的延時(shí)時(shí)間,才會(huì)執(zhí)行任務(wù)

線程池的拒絕策略

CallerRunsPolicy:重試策略,如果線程池未關(guān)閉,一直重試

AbortPolicy:直接拋出一個(gè)RejectedExecutionException異常(默認(rèn)使用)

DiscardPolicy:直接丟棄當(dāng)前任務(wù)

DiscardOldestPolicy:丟棄最舊的未處理任務(wù)

文章只是作為自己的學(xué)習(xí)筆記,借鑒了網(wǎng)上的一些案例,如果覺(jué)得有點(diǎn)幫助,希望多交流,如有錯(cuò)誤,希望指正

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容