答案
當線程池中線程執行任務的時候,任務出現未被捕獲的異常的情況下,線程池會將允許該任務的線程從池中移除並銷毀,且同時會創建一個新的線程加入到線程池中;可以通過ThreadFactory自定義線程並捕獲線程內拋出的異常,也就是說甭管我們是否去捕獲和處理線程池中工作線程拋出的異常,這個線程都會從線程池中被移除
源碼
這道面試題源碼在ThreadPoolExecutor#runWorker()方法中
任務運行是task.run(),進行了try catch處理,catch中將異常直接拋出,所以用戶沒有進行任何處理時,異常直接拋出。
(afterExecute方法是為了提供給擴展)
然后task置為null, 完成任務數加1,主要看后面的finally中調用的processWorkerExit方法
decrementWorkerCount()將CAS內存中worker存值減一,workers.remove(w)將工作線程移除
public class ThreadPoolExecutor extends AbstractExecutorService {
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
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);
}
}
}
protected void afterExecute(Runnable r, Throwable t) { }
public class ThreadPoolExecutor extends AbstractExecutorService {
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
// CAS內存中值減一
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
// 移除線程池
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}
}