ExecutorService核心参数
ExecutorService 本身是一个接口,核心参数并不在它身上,而是体现在它的主要实现类中,尤其是 ThreadPoolExecutor。下面我按「面试/实战」角度,分层次给你讲清楚。
一、ExecutorService 与 ThreadPoolExecutor 的关系
ExecutorService executor = new ThreadPoolExecutor(...);
✅ 真正有核心参数的是 ThreadPoolExecutor
二、ThreadPoolExecutor 的 7 个核心参数(最重要)
1️⃣ corePoolSize(核心线程数)
int corePoolSize
- 线程池中 长期保持存活的线程数
- 即使空闲也不会被回收(除非设置 allowCoreThreadTimeOut)
✅ 任务提交时优先创建核心线程
2️⃣ maximumPoolSize(最大线程数)
int maximumPoolSize
- 线程池 允许创建的最大线程数
- 当队列满了之后才会创建 非核心线程
3️⃣ keepAliveTime(线程空闲存活时间)
long keepAliveTime
- 非核心线程 空闲多久后被回收
- 如果
allowCoreThreadTimeOut(true),核心线程也会回收
4️⃣ unit(时间单位)
TimeUnit unit
keepAliveTime的时间单位- 常见:
TimeUnit.SECONDS
5️⃣ workQueue(工作队列)
BlockingQueue workQueue
用于存放 等待执行的任务
常见队列类型:
| 队列 | 特点 | 使用场景 |
|---|---|---|
LinkedBlockingQueue |
无界(默认 Integer.MAX_VALUE) | 任务多、允许堆积 |
ArrayBlockingQueue |
有界 | 控制资源 |
SynchronousQueue |
不存任务,直接交付 | 线程数多、响应快 |
PriorityBlockingQueue |
优先级队列 | 任务有优先级 |
⚠️ 队列类型直接影响线程池行为
6️⃣ threadFactory(线程工厂)
ThreadFactory threadFactory
- 用于 创建线程
- 可自定义:
- 线程名
- 是否为守护线程
- 优先级
new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(r, "my-thread-" + count++);
}
}
7️⃣ RejectedExecutionHandler(拒绝策略)
RejectedExecutionHandler handler
当:
- 线程数 = maximumPoolSize
- 队列已满
触发拒绝策略
常见拒绝策略
| 策略 | 说明 |
|---|---|
AbortPolicy(默认) |
抛 RejectedExecutionException |
CallerRunsPolicy |
调用者线程执行 |
DiscardPolicy |
直接丢弃 |
DiscardOldestPolicy |
丢弃队列最老任务 |
三、线程池执行流程(核心逻辑)
提交任务
↓
核心线程是否已满?
↓ 否 → 创建核心线程
↓ 是
队列是否已满?
↓ 否 → 放入队列
↓ 是
线程数是否达到最大?
↓ 否 → 创建非核心线程
↓ 是
执行拒绝策略
四、Executors 工具类(不推荐)
Executors.newFixedThreadPool()
Executors.newCachedThreadPool()
❌ 不推荐原因
- 隐藏核心参数
- 容易 OOM(无界队列或无限线程)
✅ 推荐:手动 new ThreadPoolExecutor
五、常见参数设置经验
CPU 密集型
corePoolSize ≈ CPU 核心数
queue: 有界队列
IO 密集型
corePoolSize ≈ CPU 核心数 * 2
queue: 适当大
六、一句话总结(面试版)
ExecutorService 的核心参数是指 ThreadPoolExecutor 的 7 个参数:
corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、RejectedExecutionHandler,
它们共同决定了线程池的线程创建、任务排队和拒绝策略。
如果你愿意,我可以:
- ✅ 画一张 线程池执行流程图
- ✅ 给你一个 生产级线程池配置示例
- ✅ 结合 面试题 帮你总结高频问法