工作队列容量由所选BlockingQueue实现及构造参数决定,推荐使用显式指定容量的ArrayBlockingQueue;LinkedBlockingQueue需手动设界以防OOM;SynchronousQueue无缓冲,无界队列违背背压设计;容量可依“核心线程数÷单任务耗时×最大等待时间”估算。

工作队列容量不是独立设置的参数,而是由你选用的 BlockingQueue 实现及其构造参数决定的。关键在于:选对队列类型,并在初始化时显式指定容量。
用 ArrayBlockingQueue 设置固定容量
这是最常用、最推荐的有界队列方式。容量必须在构造时传入,且不可变:
int queueCapacity = 200;
BlockingQueue<runnable> queue = new ArrayBlockingQueue(queueCapacity);
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // corePoolSize
80, // maximumPoolSize
60L, // keepAliveTime
TimeUnit.SECONDS,
queue, // ← 这里传入已设好容量的队列
new ThreadPoolExecutor.CallerRunsPolicy()
);</runnable>
一旦队列满(比如已有 200 个待执行任务),线程池会尝试扩容线程(直到 maximumPoolSize),超出则触发拒绝策略。
LinkedBlockingQueue 可设也可不设容量
它默认是无界的(内部使用 Integer.MAX_VALUE 容量),容易引发 OOM。如需可控容量,必须显式传参:
-
无界(不推荐生产环境):
new LinkedBlockingQueue() -
有界(推荐):
new LinkedBlockingQueue(500)—— 容量为 500
注意:即使设了容量,它的吞吐量通常高于 ArrayBlockingQueue,但锁粒度不同,高并发下表现需实测。
避免用 SynchronousQueue 或无界队列代替容量控制
SynchronousQueue 实际容量为 0,不缓存任务,每个提交都依赖“即时消费”,适合任务极轻、响应要求极高的场景;而无界队列(如默认 LinkedBlockingQueue)等于放弃队列水位管控,把压力全转给内存和拒绝策略,违背线程池背压设计初衷。
容量估算参考公式
合理容量不是拍脑袋定的,可按典型业务节奏估算:
- 假设核心线程数 = 10,单任务平均耗时 = 0.1 秒
- 期望最大等待时间 ≤ 2 秒 → 队列能缓冲的任务数 ≈ 10 ÷ 0.1 × 2 = 200
这个 200 就是 ArrayBlockingQueue(200) 的依据。它代表:在核心线程全忙时,新任务最多排队 2 秒,之后线程池才会扩容或拒绝。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











