面試題:線程池內線程沒有catch處理,拋出異常,線程池會怎么辦?


答案

當線程池中線程執行任務的時候,任務出現未被捕獲的異常的情況下,線程池會將允許該任務的線程從池中移除並銷毀,且同時會創建一個新的線程加入到線程池中;可以通過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);
        }
    }
}

https://blog.csdn.net/luxiaoruo/article/details/106637384


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM