优先选 ArrayBlockingQueue,因其有界性可暴露容量瓶颈并配合拒绝策略保障稳定;若用 LinkedBlockingQueue 必须显式指定容量,禁用无界构造。
线程池创建时用 LinkedBlockingQueue 还是 ArrayBlockingQueue?
取决于任务提交频率和可控性。LinkedBlockingQueue 默认无界,看似安全,但容易掩盖背压问题——当生产者(提交任务)远快于消费者(线程执行),队列无限增长,最终触发 OutOfMemoryError。ArrayBlockingQueue 是有界队列,能强制暴露容量瓶颈,配合合理的拒绝策略更利于系统稳定。
- 高吞吐、任务执行时间短且可预测 → 选
ArrayBlockingQueue,设合理容量(如核心线程数 × 2~4) - 任务来源不可控、需容忍短时突发 → 可用
LinkedBlockingQueue,但必须显式指定容量(如new LinkedBlockingQueue(1000)),绝不用无参构造 - 若用
SynchronousQueue,它不存储任务,仅作“手递手”中转,适合 CPU 密集型、希望立即触发线程创建的场景,但会频繁启停线程,慎用于 I/O 密集型
ThreadPoolExecutor 的 corePoolSize 和 maximumPoolSize 怎么设?
这不是调优起点,而是业务负载建模的结果。盲目设大值会导致线程争抢 CPU 或阻塞在 I/O 上,反而降低吞吐;设太小则任务积压、响应延迟升高。
- CPU 密集型任务:理论上限 ≈
Runtime.getRuntime().availableProcessors(),corePoolSize和maximumPoolSize可设为相同值,避免线程上下文切换开销 - I/O 密集型任务(如 HTTP 调用、DB 查询):需估算平均 I/O 等待时间占比,公式参考:
corePoolSize ≈ CPU 核数 / (1 - 阻塞系数),其中阻塞系数常取 0.8~0.9,即单线程约 80% 时间在等 I/O - 永远不要把
maximumPoolSize设为Integer.MAX_VALUE—— 这会让线程池在队列满后无限制新建线程,极大概率 OOM
为什么 submit(Runnable) 返回的 Future 调用 get() 会阻塞?
因为 Future.get() 是同步等待语义,它会挂起当前

get(),而那个任务又排在队列里,无人执行。
- 避免在
Runnable或Callable内部调用同一线程池中其他任务的future.get() - 如需组合多个异步结果,优先用
CompletableFuture.supplyAsync(..., executor)配合thenCombine/allOf,它们不阻塞线程,而是注册回调 - 若必须阻塞等待,确保调用方不在该线程池的工作线程中(例如放在 Servlet 线程或独立的调度线程里)
关闭线程池时,shutdown() 和 shutdownNow() 的实际行为差异
shutdown() 是温和终止:不再接受新任务,但会等所有已提交任务(包括队列中未执行的)完成;shutdownNow() 是强制中断:尝试停止正在执行的任务(通过 Thread.interrupt()),并清空队列、返回未执行任务列表。
- 绝大多数场景应优先用
shutdown()+awaitTermination(long, TimeUnit),给任务留出合理收尾时间(如释放连接、刷盘日志) -
shutdownNow()仅适用于可中断任务(即代码中检查了Thread.currentThread().isInterrupted()并主动退出),否则中断信号被忽略,任务仍会跑完 - Spring 中用
@PreDestroy关闭线程池时,务必加超时等待逻辑,否则应用可能假死在关闭阶段
executor.shutdown();
try {
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
executor.shutdownNow();
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
System.err.println("线程池未正常关闭");
}
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}真正难的不是选哪个队列或设几个线程,而是理解每个参数背后对资源竞争、任务生命周期和错误传播路径的影响。多数线上问题,都出在“以为设了线程池就等于并发安全”,却没管住任务本身的阻塞点和依赖关系。








