1.線程池的工作原理:

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條目;