Java線程池ThreadPoolExcutor

1.線程池的工作原理:

線程池.png

1.1線程池剛創(chuàng)建時,里面沒有一個線程。任務(wù)隊列是作為參數(shù)傳進來的。不過,就算隊列里面有任務(wù),線程池也不會馬上執(zhí)行它們。

1.2.當(dāng)調(diào)用execute()方法添加一個任務(wù)時,線程池會做如下判斷:
a.如果正在運行的線程數(shù)小于corePoolSize,那么馬上創(chuàng)建線程運行這個任務(wù)。
b.如果正在運行的線程數(shù)大于或者等于corePoolSize,那么將這個任務(wù)放入隊列。
c.如果這個時候隊列滿了,而且正在運行的線程數(shù)量小于maximumPoolSize,那么還是要創(chuàng)建線程運行這個任務(wù)。
d.如果隊列滿了,而且正在運行的線程數(shù)量大于或等于 maximumPoolSize,那么線程池會拋出異常,告訴調(diào)用者“我不能再接受任務(wù)了”

1.3當(dāng)一個線程完成任務(wù)時,它會從隊列中取下一個任務(wù)來執(zhí)行。

1.4當(dāng)一個線程無事可做,超過一定的時間(keepAliveTime)時,線程池會判斷,如果當(dāng)前運行的線程數(shù)大于corePoolSize時,那么這個線程會被停用掉,所以線程池的所有任務(wù)完成后,它最終會收縮到corePoolSize的大小。

2.線程池有哪些配置

線程池可以使用java.util.concurrent.ThreadPoolExecutor來創(chuàng)建,在該類中包含最全參數(shù)的構(gòu)造函數(shù)。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

maximumPoolSize:線程池最大線程數(shù),表示在線程池中最多能創(chuàng)建多少個線程。如果當(dāng)線程池中的數(shù)量到達這個數(shù)字時,新來的任務(wù)會拋出異常。
keepAliveTime:表示線程沒有任務(wù)執(zhí)行時最多能保持多少時間會停止,然后線程池的數(shù)目維持在corePoolSize。
unit:參數(shù)keepAliveTime的時間單位
workQueue:一個阻塞隊列,用來存儲等待執(zhí)行的任務(wù),如果當(dāng)前對線程的需求超過了corePoolSize大小,才會放在這里。
threadFactory:線程工廠,主要用來創(chuàng)建線程,比如指定線程的名字。
handler:如果線程池已滿,新的任務(wù)處理方式。
3.線程池的阻塞隊列包含哪幾種選擇?

1. ArrayBlockingQueue
2. LinkedBlockingQueue
3. PriorityBlockingQueue
4. SynchronousQueue

ArrayBlockingQueue是一個有邊界的阻塞隊列,它的內(nèi)部實現(xiàn)是一個數(shù)組。它的容量在初始化時就確定不變。
LinkedBlockingQueue:阻塞隊列大小的配置是可選的,其內(nèi)部實現(xiàn)是一個鏈表。
PriorityBlockingQueue:是一個沒有邊界的隊列,所有插入到PriorityBlockingQueue的對象必須實現(xiàn)java.lang.Comparable接口,隊列優(yōu)先級的排序就是按照我們對這個接口的實現(xiàn)來定義的。
SynchronousQueue隊列內(nèi)部僅允許容納一個元素。當(dāng)一個線程插入一個元素后會被阻塞,除非這個元素被另一個線程消費。

4.如果線程池已經(jīng)滿了可是還有新的任務(wù)提交怎么辦?

線程池已經(jīng)滿的定義,是指運行線程數(shù) == maximumPoolSize,并且workQueue是有界隊列并且已滿。
這時候再提交任務(wù)怎么辦呢?線程池會將任務(wù)傳遞給最后一個參數(shù)RejectedExecutionHandler來處理,比如打印報錯日志、拋出異常、存儲到Mysql/redis用于后續(xù)處理等等,線程池默認(rèn)也提供了幾種處理方式見第5條目;

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

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

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