★ 线程池的核心参数与执行流程是怎样的?

结论先行:ThreadPoolExecutor 有七个核心参数:核心线程数、最大线程数、空闲存活时间、时间单位、阻塞队列、线程工厂、拒绝策略。执行铁律是:先占核心线程,核心满则排队进队列,队列满才扩到最大线程数,最大也满则触发拒绝策略——注意顺序是先排队、后扩线程,这与直觉相反,是高频考点。

七大参数

参数含义
corePoolSize核心线程数,常驻不回收(allowCoreThreadTimeOut 除外)
maximumPoolSize线程数上限
keepAliveTime / unit非核心线程空闲存活时间
workQueue任务等待队列(有界/无界)
threadFactory创建线程的工厂,建议自定义命名便于排查
handler队列满且线程达上限时的拒绝策略

新任务提交流程

  1. 工作线程数 < corePoolSize → 直接新建核心线程执行任务。
  2. 工作线程数 ≥ corePoolSize → 任务放入 workQueue 排队等待。
  3. 队列已满且线程数 < maximumPoolSize → 新建非核心线程执行。
  4. 队列已满且线程数已达 maximumPoolSize → 交给 RejectedExecutionHandler。
import java.util.concurrent.*;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                2,                             // corePoolSize
                4,                             // maximumPoolSize
                60, TimeUnit.SECONDS,          // 非核心线程空闲 60s 回收
                new ArrayBlockingQueue<>(10),  // 有界队列
                r -> new Thread(r, "biz-pool-" + r.hashCode()),
                new ThreadPoolExecutor.AbortPolicy());
        pool.execute(() -> System.out.println("task running"));
        pool.shutdown(); // 不再接新任务,跑完存量后关闭
    }
}

常见追问 / 记忆点

  • 记忆点:一条口诀“核心 → 队列 → 扩容 → 拒绝”,扩线程永远排在排队之后。
  • 追问:execute 提交的 Runnable 若抛异常,线程会退出并打印栈,最好在任务内部捕获处理。
  • 追问:核心线程默认不回收;prestartAllCoreThreads() 可预热线程,避免首批请求因建线程变慢。
笔记加载中…