<font color="#2E86C1">Java线程池源码</font>
2025年Java面试宝典网盘下载(点击蓝色链接即可保存)
最近在面试中被问烂的Java线程池问题,我发现很多同学能背出七大参数、四种拒绝策略,但一旦问到源码实现就支支吾吾。今天就带大家深入ThreadPoolExecutor源码,看看面试官最想听到的底层逻辑。

线程池的核心参数藏在哪里?
打开ThreadPoolExecutor.java,前200行藏着6个关键状态位:
- RUNNING:接收新任务且处理队列任务
- SHUTDOWN:不接收新任务但处理队列任务
- STOP:中断所有任务
- TIDYING:所有任务终止
- TERMINATED:terminated()执行完毕
聪明的面试者会指出这里用了32位整型的高3位存状态,低29位存工作线程数。这种位运算的骚操作既省内存又保证原子性,正是源码的精华所在。
execute()方法的三重境界
public void execute(Runnable command) {
// 源码删减版
if (workerCount < corePoolSize) {
addWorker(command, true);
return;
}
if (workQueue.offer(command)) {
// 二次检查
}
else if (!addWorker(command, false)) {
reject(command);
}
}
这个经典方法藏着三个面试考点:
- 优先创建核心线程:直接调用addWorker
- 队列缓冲机制:offer()失败才会扩容
- 双检锁设计:防止并发时队列已满但线程数超限

Worker类的生存之道
每个Worker都是个AQS同步器,继承自AbstractQueuedSynchronizer。为什么要这样设计?其实是为了实现任务执行期间锁定线程,防止线程被重复中断。
在runWorker()方法里有个死循环:
while (task != null || (task = getTask()) != null) {
// 执行任务
}
注意getTask()方法从阻塞队列取任务时,会根据allowCoreThreadTimeOut配置决定是否允许回收核心线程。这个细节常被忽略,但却是线程池动态调整的关键。
拒绝策略的源码实现
四种拒绝策略都实现了RejectedExecutionHandler接口,以AbortPolicy为例:
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException();
}
有趣的是CallerRunsPolicy的实现:
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
这种策略会让提交任务的线程自己执行任务,相当于降级处理。在流量突增的场景下,这种策略比直接抛异常更友好。

高频面试问题破解
当被问到"线程池参数怎么设置"时,不要直接背公式。可以这样回答:
- IO密集型任务建议核心线程数=CPU核数*2
- 队列选择优先用LinkedBlockingQueue(无界需谨慎)
- 监控线程池状态可以通过继承ThreadPoolExecutor重写beforeExecute()
需要购买面试鸭会员的同学注意啦!通过面试鸭返利网找我购买可返25元,海量真题解析和源码分析资料任你下载。
最后提醒大家,理解线程池源码要抓住三个关键点:状态流转机制、任务执行流程、资源回收逻辑。把这些底层原理讲清楚,面试官绝对会眼前一亮。建议配合网盘里的《2025年Java面试宝典》系统复习,祝大家面试顺利!


