先上個網(wǎng)圖說明下線程池的執(zhí)行過程
image.png
來看下線程池的執(zhí)行過程
image.png
1.當(dāng)線程池數(shù)量小于核心線程數(shù) 直接創(chuàng)建核心線程
2.隊列是否已滿萤皂,沒有的話 放入隊列
3.放入隊列失敗 添加非核心線程 失敗的話 處理失敗
很容易看出核心方法是addWork
這個方法是添加線程執(zhí)行的双揪,不做過多解釋愤诱。
在這個方法中調(diào)用了 start
方法藏否,這個很熟悉是啟動線程的方法介陶。
順藤破瓜看看Work的run方法 只有一個runWork方法
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
// 保證核心線程默認(rèn)情況下不會被銷毀而是進(jìn)行阻塞(getTask()核心線程)
while (task != null || (task = getTask()) != null) {
w.lock();
// 死循環(huán)保證線程不會結(jié)束
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
//執(zhí)行真正的任務(wù)
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
重點是 getTask
的執(zhí)行 包含了線程阻塞
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
// 線程結(jié)束
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
// 非核心線程超過時間會被淘汰 返回null 退出線程
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
// 小于核心線程蔽氨,當(dāng)前待線程為0 阻塞線程保證默認(rèn)情況下的核心線程不會銷毀
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
大體意思就是
不停的取task
超時退出線程
沒有任務(wù)時 阻塞線程 可以設(shè)置核心線程可以退出融师,這個時候線程不會阻塞