runWorker方法相對比較簡單盖溺,主要有個循環(huán)
try{
while (task != null || (task = getTask()) != null) {
??? …
try {
?????? ?…
??????? task.run();
???? } finally {
???? ? task = null;
???????? …
??? }
}
}finally {
?????? processWorkerExit(w,completedAbruptly);
}
可以看到task
!=null 即啟動線程時傳進來的第一個任務(wù),執(zhí)行完之后,runWorker并不會退出搔扁,而是線程復(fù)用繼續(xù)getTask()從隊列中獲取任務(wù),直至所有任務(wù)都執(zhí)行完敲才,getTask()返回空晦墙。
getTask()也比較簡單,主要代碼就是:
Runnable r = timed ?
workQueue.poll(keepAliveTime,
TimeUnit.NANOSECONDS) :
workQueue.take();
如果設(shè)置了超時就poll歧斟,否則就take()一直阻塞纯丸,直到從隊列中獲取到任務(wù)為止。一般情況静袖,如果線程池數(shù)大于core的時候觉鼻,需要回收(poll),線程數(shù)等于core時核心線程是不會被回收的勾徽,就一直阻塞等待任務(wù)加入隊列滑凉。
processWorkerExit(w, completedAbruptly); 這個方法,是在所有任務(wù)都已執(zhí)行完或發(fā)生異常時執(zhí)行喘帚,completedAbruptly=true 表示異常退出畅姊,false表示正常退出。
processWorkerExit方法相對來說也挺好理解:
1吹由、線程池完成任務(wù)數(shù)增加當前線程的完成任務(wù)數(shù)若未,workers集合移除當前worker
completedTaskCount += w.completedTasks;
workers.remove(w);
2、tryTerminate(); //嘗試結(jié)束線程池
3倾鲫、這時候線程池狀態(tài)還是小于STOP:
如果當前線程是異常退出粗合,則需要再啟動一個線程繼續(xù)去執(zhí)行任務(wù)隊列的任務(wù)萍嬉;
正常退出邏輯:min:線程池最小空閑數(shù),允許核心線程超時則為0隙疚,否則為核心線程池大小corePoolSize壤追,而如果min=0并且任務(wù)列表不為空,則min=1即至少要保證一個線程來處理隊列中的任務(wù)供屉。if
(workerCountOf(c) >= min) 即當前線程池中的工作線程大于最小空閑數(shù)行冰,就不用擔心了,直接返回伶丐。否則就跟異常退出一樣悼做,需要再啟動一個線程繼續(xù)執(zhí)行隊列中的任務(wù)』┗辏總結(jié)一下就是以下三種情況需要新增一個Worker來替代原來的:
// 1. 用戶執(zhí)行的任務(wù)發(fā)生了異常
// 2. Worker數(shù)量比線程池基本大小要小
// 3. 阻塞隊列不空但是沒有任何Worker在工作
if (runStateLessThan(c, STOP)) {
?????? if(!completedAbruptly) {
????????????? intmin = allowCoreThreadTimeOut ? 0 : corePoolSize;
????????????? if(min == 0 && ! workQueue.isEmpty())
???????????????????? min= 1;
????????????? if(workerCountOf(c) >= min)
???????????????????? return;// replacement not needed
?????? }
?????? addWorker(null,false);
}