日期: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。
面试官追问
- 如果任务是 CPU 密集型,100 个线程合理吗?
- 为什么队列不能直接设置为 1000?
- 如果任务持续到达而非一次性 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 密集任务。