应选有界队列:容量固定防oom,触发线程扩容应对突发流量,提供明确背压机制;无界队列虽吞吐高但易致内存耗尽、雪崩风险大,synchronousqueue适合低延迟场景但需配好拒绝策略。

选有界还是无界队列,不能只看“快不快”,关键得看你的线程池怎么用、任务压在哪、内存扛不扛得住。性能不是单一维度的吞吐数字,而是响应延迟、内存稳定性、线程伸缩行为的综合体现。
有界队列(如 ArrayBlockingQueue、带容量的 LinkedBlockingQueue)
容量固定,入队满则阻塞或返回 false,直接触发线程池扩容逻辑(只要未达 maximumPoolSize)。
- 线程数可弹性增长:队列满 + 当前线程数
- 内存可控:最大积压量 = 队列容量 + 最大线程数 × 单任务开销,OOM 风险低
- 背压明确:生产者被阻塞或收到拒绝,能倒逼上游限流、降级或重试
- 吞吐可能受限:ArrayBlockingQueue 单锁竞争高时,put/take 串行化明显;LinkedBlockingQueue 双锁缓解但仍有边界
无界队列(如 LinkedBlockingQueue(无参)、PriorityBlockingQueue)
默认容量 Integer.MAX_VALUE,offer() 几乎总成功,线程池永远不认为“入队失败”,因此不会新建非核心线程,线程数恒等于 corePoolSize。
- 线程数稳定、调度开销小:避免频繁创建/销毁线程,上下文切换少
- 短期吞吐高、延迟平滑:任务全进队列排队,不触发拒绝也不扩线程,适合处理节奏均匀的小任务
- 内存风险极高:任务堆积 → 队列持续扩容 → 堆内存耗尽 → OOM;GC 对强引用任务束手无策
- 无真实背压:上游感知不到压力,容易雪崩;监控告警滞后(等 OOM 才发现)
SynchronousQueue:特殊的“零容量”有界队列
它不存储任务,每个 put 必须配一个 take,本质是线程间直接移交。虽然容量为 0,但行为上最激进地推动线程扩容。
- 极致低延迟:任务不落地,免序列化、免队列拷贝
- 线程数最贴近真实并发:几乎每次提交都尝试新建线程(直到 maximumPoolSize),适合网关、RPC 等对并发敏感场景
- 必须配好拒绝策略:否则流量洪峰直接打穿 maximumPoolSize,抛 RejectedExecutionException
实际选型建议
别纠结“哪个更快”,先问自己三个问题:
- 任务对象大不大?比如含大 byte[]、JSON 字符串 → 选有界,防堆爆
- 任务产生速率是否远超消费能力?波动是否剧烈?→ 有界 + 合理拒绝策略更安全
- 能否接受任务被拒绝或上游阻塞?能 → 有界;不能且内存充足 → 显式设界的 LinkedBlockingQueue(比如 1024),绝不用无参构造
真正高性能的线程池,不在队列本身多快,而在它让系统行为可预测、可监控、可收敛。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











