前面簡單學(xué)習(xí)了JUC同步輔助類,今天一起走進(jìn)線程池的美妙新世界。
一、從新建線程池談起
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
類的區(qū)別
Executor是執(zhí)行者接口俐筋,通過execute方法執(zhí)行Runnable任務(wù);
ExecutorService是執(zhí)行者服務(wù)接口严衬,通過submit將任務(wù)提交給Executor執(zhí)行澄者;
ThreadPoolExecutor是真正的實(shí)現(xiàn)類;
Executors是靜態(tài)工廠類请琳,可以返回ExecutorService等粱挡;參數(shù)概念
corePoolSize : 線程池中允許同時運(yùn)行的線程數(shù);
maximumPoolSize : 線程池中允許創(chuàng)建的最大線程數(shù)俄精;
keepAliveTime:線程池空閑后询筏,超過此時間的線程會被終止;
workQueue :線程任務(wù)阻塞隊(duì)列竖慧;
defaultThreadFactory : 返回線程工廠屈留,線程池中的線程均是由線程工廠創(chuàng)建;
defaultHandler:任務(wù)添加到線程池中测蘑,線程池拒絕時采取的策略灌危;
二、以execute方法為重
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//策略一:線程池中運(yùn)行數(shù)量小于corePoolSize時碳胳,直接新建任務(wù)
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//策略二:線程池中大于等于corePoolSize時勇蝙,且線程池狀態(tài)允許時,將任務(wù)添加到阻塞隊(duì)列中
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//策略三:線程池中大于等于corePoolSize時挨约,且線程池狀態(tài)不允許時味混,直接新建任務(wù)
else if (!addWorker(command, false))
reject(command);
}
- addWork源碼解讀
- 上面代碼中多次談到線程池狀態(tài)及拒絕策略产雹,下一步深入理解
三、線程池狀態(tài)及轉(zhuǎn)換
- 與線程的五種狀態(tài)不同翁锡,線程池的五種狀態(tài)及其轉(zhuǎn)換如下圖所示:
Running:能接受新任務(wù)蔓挖,且處理已添加任務(wù);(對應(yīng)于isRunning檢測)
ShutDown:不能接受新任務(wù)馆衔,可處理已添加任務(wù)瘟判;
Stop:不能接受新任務(wù),且會中斷已處理任務(wù)角溃;
Tidying:所有任務(wù)已經(jīng)終止拷获;
Terminated:Tidying狀態(tài)后,執(zhí)行鉤子函數(shù)terminate减细,進(jìn)入此狀態(tài)匆瓜;
四、拒絕策略
AbortPolicy:當(dāng)任務(wù)添加到線程池中被拒絕時未蝌,它將拋出 RejectedExecutionException 異常驮吱;
CallerRunsPolicy:當(dāng)任務(wù)添加到線程池中被拒絕時,會在線程池當(dāng)前正在運(yùn)行的Thread線程池中處理被拒絕的任務(wù)萧吠;
DiscardOldestPolicy:當(dāng)任務(wù)添加到線程池中被拒絕時左冬,線程池會放棄等待隊(duì)列中最舊的未處理任務(wù),然后將被拒絕的任務(wù)添加到等待隊(duì)列中怎憋;
DiscardPolicy:當(dāng)任務(wù)添加到線程池中被拒絕時,線程池將丟棄被拒絕的任務(wù)九昧;