線程池的基本結構
線程池主要線程和一個阻塞隊列組成。
線程池的執(zhí)行流程
大體流程
當一個任務提交到線程池時
第一步 會先判斷線程池里的核心線程是否都在執(zhí)行任務;如果有可用線程并且當前線程池中的核心線程數還小于 corePoolSize則創(chuàng)建線程使用膘茎,否則就進入下一個流程;
第二步 線程池判斷工作隊列是否已滿酷誓,如果工作隊列沒有滿披坏,則將新提交的任務存儲在這個工作隊列里。如果工作隊列滿了盐数,則進入下個流程刮萌;
第三步 判斷線程池里的線程是否都處于工作狀態(tài),如果沒有娘扩,查看一下當前線程數是否到達maximumPoolSize着茸,如果還未到達壮锻,就繼續(xù)創(chuàng)建線程。如果已經到達了涮阔,就交給RejectedExecutionHandler來決定怎么處理這個任務猜绣。
execute()方法
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//如果線程數大于等于基本線程數或者線程創(chuàng)建失敗,將任務加入隊列
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
//線程池處于運行狀態(tài)并且加入隊列成功
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
//線程池不處于運行狀態(tài)或者加入隊列失敗敬特,則創(chuàng)建線程(創(chuàng)建的是非核心線程)
else if (!addIfUnderMaximumPoolSize(command))
//創(chuàng)建線程失敗掰邢,則采取阻塞處理的方式
reject(command); // is shutdown or saturated
}
}
addIfUnderCorePoolSize()
private boolean addIfUnderCorePoolSize(Runnable firstTask) {
Thread t = null;
final ReentrantLock mainLock = this.mainLock;
//阻塞鎖
mainLock.lock();
try {
if (poolSize < corePoolSize && runState == RUNNING)
t = addThread(firstTask);
} finally {
mainLock.unlock();
}
if (t == null)
return false;
//啟動線程
t.start();
return true;
}
addThread()方法
private Thread addThread(Runnable firstTask) {
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w);
if (t != null) {
w.thread = t;
workers.add(w);
int nt = ++poolSize;
if (nt > largestPoolSize)
largestPoolSize = nt;
}
return t;
}