Yihui’s Blog

1000 个任务,每个 0.1s,最大响应时间 1s,线程池参数怎么设置?

日期:2026-07-11
标签:#面试 #八股 #后端 #Java #线程池 #场景题

一句话答案

理想无开销下至少需要 1000 × 0.1 / 1 = 100 个并发执行槽位;可从 core=max=100、有界队列至少 900 起步,但真实配置必须结合任务是 CPU 还是 I/O、机器核数和安全余量压测。

面试口语版

我会先问 1000 个任务是否同时到达,以及 1 秒指全部完成还是单任务 P99。若同时到达且每个稳定占用 0.1 秒,100 个并发线程可分 10 批完成,理论末批正好 1 秒,所以最低并发度是 100。可以设核心和最大线程都是 100、队列容量至少 900,避免临时线程创建抖动;生产中要给调度、GC 和尾延迟留余量,例如从 120~150 压测。但如果任务是 CPU 密集型而机器只有 8 核,开 100 线程并不能满足目标,应增加机器、拆分任务或调整 SLO。

计算与参数

所需并发度 >= 任务数 × 单任务耗时 ÷ 最大完成时间
             >= 1000 × 0.1 ÷ 1 = 100
  • corePoolSize = maximumPoolSize = 100:稳定批任务可避免频繁扩缩容。
  • queueCapacity >= 900:只适用于这 1000 个任务的单批模型;持续流量需按允许排队时间重新计算。
  • 拒绝策略:不能静默丢任务,可快速失败、调用方执行或持久化,取决于业务。

关键细节

  • ThreadPoolExecutor 默认先占满核心线程,再入队;有界队列未满时不会扩到 maximum。
  • 单任务 0.1 秒应使用 P99 而非平均值估算。
  • 线程数公式只描述并发需求,不代表硬件能承载。
  • 必须监控活跃线程、队列等待时间、拒绝数和任务 P99。

面试官追问

  1. 如果任务是 CPU 密集型,100 个线程合理吗?
  2. 为什么队列不能直接设置为 1000?
  3. 如果任务持续到达而非一次性 1000 个,怎么计算?

面试官追问参考答案

1. 如果任务是 CPU 密集型,100 个线程合理吗?

通常不合理,CPU 密集型线程数应接近可用核数,过多只增加上下文切换。若 1000 个 CPU 任务必须 1 秒完成,需要约 100 个等效计算核心或更多实例,而不是在少核机器上堆线程。

2. 为什么队列不能直接设置为 1000?

容量 1000 在这批任务中可能可用,但过大队列会把过载隐藏成排队,任务尚未执行就超过 1 秒 SLO,并占用内存。队列应由允许排队时间和消费速率计算,配合快速拒绝与背压。

3. 如果任务持续到达而非一次性 1000 个,怎么计算?

用到达率 λ 和服务时间 W 估算并发需求 L≈λW,再为峰值和尾延迟留余量;必须保证长期到达率小于处理能力,否则队列必然无限增长。通过压测校准线程数和最大可接受队列等待。

学习清单

  • 会用并发度公式和 Little’s Law 粗算。
  • 能区分 CPU 与 I/O 密集任务。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts