通過前面的章節,我們學習了可以通過ThreadPoolExecutor來創建一個線程池。
那麼接下來我們分析一下ThreadPoolExecutor的源碼,看看它具體是如何工作的。
我們看一下使用execute(Runnable task)執行一個任務的時候,到底發生了什麼(代碼進過簡化):
先簡單描述一下當我們提交一個任務到線程池中後發生了什麼:
具體源碼如下:
public void execute(Runnable task) {
//取出當前線程池活躍的線程數。
//ctl是一個原子類型的對象(final AtomicInteger ctl),用來保存當前線程池的線程數以及線程池的狀態。
int c = ctl.get();
//如果當前的活躍線程數小於核心線程數,即使現在有空閒線程,也創建一個新的線程,去執行這個任務
if (workerCountOf(c) < corePoolSize) {
//創建一個新的線程,去執行這個任務。
if (addWorker(task, true))
return;
//如果執行到這一句說明任務沒有分配成功。
//所以獲得當前線程池狀態值,爲後面的檢查做準備。
c = ctl.get();
}
//如果大於核心線程數,檢查一下線程池是否還處於運行狀態,並嘗試把任務放入到blockingQueue任務隊列中。
if (isRunning(c) && workQueue.offer(task)) {
//這裏再次檢查一下線程池的狀態
int recheck = ctl.get();
if (! isRunning(recheck) && remove(task))
//如果線程池不處於運行狀態的話,就把我們剛纔添加進任務隊列中的任務移出,並拒絕這個任務。
reject(task);
//檢查如果當前線程池中的線程數,如果爲0了,就爲線程池創建新線程(因爲有可能之前存活的線程在上一次檢查過後死亡了)
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//執行到這一句,說明隊列滿了。這時,如果當前線程池中的線程數還沒有超過最大線程數,就創建一個新的線程去執行這個任務,如果失敗就拒絕這個任務。
else if (!addWorker(task, false))
reject(task);
}
以上就是ThreadPoolExecutor的基本執行流程。