1. 核心参数详解
ThreadPoolExecutor 的标准构造函数包含 7 个参数,面试时建议按顺序清晰阐述:
corePoolSize(核心线程数)- 含义:线程池维护的最小线程数量。即使这些线程处于空闲状态,也不会被销毁(除非设置了
allowCoreThreadTimeOut)。 - 作用:保证基本的并发处理能力。
- 含义:线程池维护的最小线程数量。即使这些线程处于空闲状态,也不会被销毁(除非设置了
maximumPoolSize(最大线程数)- 含义:线程池允许创建的最大线程数量。
- 作用:控制资源消耗上限,防止无限制创建线程耗尽 CPU/内存。
keepAliveTime(存活时间)- 含义:当线程数大于核心线程数时,多余的空闲线程在终止前等待新任务的最长时间。
- 作用:动态回收线程资源,降低系统开销。
unit(时间单位)- 含义:
keepAliveTime的时间单位(如秒、毫秒)。
- 含义:
workQueue(任务队列)- 含义:用于保存等待执行任务的阻塞队列。
- 常见类型:
ArrayBlockingQueue:有界,适合防止资源耗尽。LinkedBlockingQueue:默认无界(需小心 OOM),吞吐量通常更高。SynchronousQueue:不存储元素,直接移交,适合高并发短任务。
threadFactory(线程工厂)- 含义:用于创建新线程的工厂。
- 作用:建议自定义,设置有意义的线程名称(如
order-service-pool-%d),这对生产环境排查日志至关重要。
handler(拒绝策略)- 含义:当队列满且线程达到最大值时,对新任务的处理策略。
- JDK默认策略:
AbortPolicy:抛异常(默认)。CallerRunsPolicy:调用者自己运行(既不丢弃任务,又能减缓提交速度)。DiscardPolicy:直接丢弃。DiscardOldestPolicy:丢弃队列中最老的任务。
2. 进阶:参数配置最佳实践
面试官常追问:“这些参数该怎么设置?”
- CPU 密集型任务(如加密、计算):
- 配置:
N + 1(N 为 CPU 核心数)。 - 理由:线程主要在计算,减少上下文切换。
- 配置:
- I/O 密集型任务(如读写库、接口调用):
- 配置:
2N或N / (1 - 阻塞系数)。 - 理由:线程大部分时间在等待 I/O,需要更多线程来利用 CPU。
- 配置:
3. 总结
回答总结: “线程池包含核心线程数、最大线程数、空闲存活时间、时间单位、任务队列、线程工厂和拒绝策略这 7 个参数。配置时需根据业务类型(CPU密集 vs IO密集)合理设置大小,并强烈建议使用有界队列和自定义线程工厂(命名),以确保系统的稳定性和可维护性。”