Java 面试宝典:线程池的核心线程会被回收吗?

693 阅读1分钟

大家好,我是大明哥,一个专注「死磕 Java」系列创作的硬核程序员。

本文已收录到我的技术网站:www.skjava.com。有全网最优质的系列文章、Java 全栈技术文档以及大厂完整面经


回答

默认情况下,线程池的核心线程是不会被回收的,即使它们处于空闲状态。但是 ThreadPoolExecutor 还是提供了一个参数来控制这个行为,通过 allowCoreThreadTimeOut(true)设置后,核心线程在空闲超过keepAliveTime时就会被回收。

我们直接看源码,直接看 ThreadPoolExecutorrunWorker()

   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) {
               // 不断从任务队列中拿任务执行,直到获取为空
            }
            completedAbruptly = false;
        } finally {
            // 当没有任务后,执行
            processWorkerExit(w, completedAbruptly);
        }
    }

当任务队列中没有任务执行了就会执行 processWorkerExit(),该方法主要用于清理一些工作线程:

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        // ...

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                // 如果 allowCoreThreadTimeOut = true,则 min 为 0
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                // min == 0 但是工作线程为空位,则至少需要创建一个线程,否则就是 0
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                // 线程池中的线程数 >= min 就直接退出
                if (workerCountOf(c) >= min)
                    // 这里直接返回
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }

processWorkerExit() 中可以看出,如果 allowCoreThreadTimeOut 设置为 true,则大概率情况下是不会调用 addWorker(null, false) 去创建线程的,它会直接返回,线程自然消亡。


关于线程池的原理,请阅读:什么是线程池?它的核心原理是什么?