线程池的核心线程会被回收吗?

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

在java.util.concurrent.java.util.concurrent可以找到

    /**
     * If false (default), core threads stay alive even when idle.
     * If true, core threads use keepAliveTime to time out waiting
     * for work.
     */
     // 翻译:如果为 false(默认值),即使在空闲状态下核心线程也保持存活。如果为 true,
     // 核心线程使用 keepAliveTime 来超时等待工作。
    private volatile boolean allowCoreThreadTimeOut;
    /**
     * Main worker run loop.  Repeatedly gets tasks from queue and
     * executes them, while coping with a number of issues:
     *
     * 1. We may start out with an initial task, in which case we
     * don't need to get the first one. Otherwise, as long as pool is
     * running, we get tasks from getTask. If it returns null then the
     * worker exits due to changed pool state or configuration
     * parameters.  Other exits result from exception throws in
     * external code, in which case completedAbruptly holds, which
     * usually leads processWorkerExit to replace this thread.
     *
     * 2. Before running any task, the lock is acquired to prevent
     * other pool interrupts while the task is executing, and then we
     * ensure that unless pool is stopping, this thread does not have
     * its interrupt set.
     *
     * 3. Each task run is preceded by a call to beforeExecute, which
     * might throw an exception, in which case we cause thread to die
     * (breaking loop with completedAbruptly true) without processing
     * the task.
     *
     * 4. Assuming beforeExecute completes normally, we run the task,
     * gathering any of its thrown exceptions to send to afterExecute.
     * We separately handle RuntimeException, Error (both of which the
     * specs guarantee that we trap) and arbitrary Throwables.
     * Because we cannot rethrow Throwables within Runnable.run, we
     * wrap them within Errors on the way out (to the thread's
     * UncaughtExceptionHandler).  Any thrown exception also
     * conservatively causes thread to die.
     *
     * 5. After task.run completes, we call afterExecute, which may
     * also throw an exception, which will also cause thread to
     * die. According to JLS Sec 14.20, this exception is the one that
     * will be in effect even if task.run throws.
     *
     * The net effect of the exception mechanics is that afterExecute
     * and the thread's UncaughtExceptionHandler have as accurate
     * information as we can provide about any problems encountered by
     * user code.
     *
     * @param w the worker
     */
    /**
    主要的工作线程运行循环。反复从队列中获取任务并执行它们,同时处理一些问题:
    我们可能以一个初始任务开始,在这种情况下我们不需要获取第一个任务。否则,只要线程池在运行,我们就从 getTask 方法获取任务。如果它返回 null,那么由于线程池状态或配置参数的改变,工作线程退出。其他退出情况是由于外部代码抛出异常,在这种情况下 completedAbruptly 被设置为 true,这通常会导致 processWorkerExit 方法替换这个线程。
    在运行任何任务之前,获取锁以防止在任务执行期间其他对线程池的中断,然后我们确保除非线程池正在停止,否则这个线程的中断标志不会被设置。
    每个任务运行之前会调用 beforeExecute 方法,这个方法可能会抛出异常,在这种情况下我们使线程死亡(以 completedAbruptly 为 true 打破循环)而不处理任务。
    假设 beforeExecute 正常完成,我们运行任务,收集任务抛出的任何异常以发送给 afterExecute。我们分别处理 RuntimeException、Error(规范保证我们捕获这两种异常)和任意的 Throwables。因为我们不能在 Runnable.run 中重新抛出 Throwables,所以我们在抛出时将它们包装在 Errors 中(传递给线程的 UncaughtExceptionHandler)。任何抛出的异常也会保守地导致线程死亡。
    在 task.run 完成后,我们调用 afterExecute,它也可能抛出异常,这也会导致线程死亡。根据 JLS 第 14.20 节,这个异常将是有效的,即使 task.run 抛出了异常。
    异常处理机制的最终效果是 afterExecute 和线程的 UncaughtExceptionHandler 能够尽可能准确地获得用户代码遇到的任何问题的信息。
    @param w 工作线程
    */
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@程序员小袁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值