应根据场景选择BlockingQueue:任务稳定选LinkedBlockingQueue,突发性强且需控内存选ArrayBlockingQueue,有优先级需求选PriorityBlockingQueue,追求极致吞吐且任务极短选SynchronousQueue。

选择合适的 BlockingQueue 类型,关键看任务提交节奏、内存承受力、是否允许丢弃、以及对响应性或公平性的要求。没有“最好”的队列,只有“最适合当前场景”的队列。
任务量稳定且可控 → 用 LinkedBlockingQueue(可选容量)
这是最常用的默认选择(Executors.newFixedThreadPool 内部使用无界版本)。它基于链表,吞吐量高,支持高并发入队/出队。
- 若能预估最大待处理任务数,建议设容量(如
new LinkedBlockingQueue(1000)),避免 OOM - 无界队列(
new LinkedBlockingQueue())看似安全,但可能掩盖任务积压问题,导致内存持续增长 - 适用于任务执行时间较均匀、系统资源较充裕的后台服务
任务突发性强、需控内存 + 可接受丢弃 → 用 ArrayBlockingQueue
基于数组的有界队列,创建时必须指定容量,线程安全且性能稳定,插入/删除时间复杂度均为 O(1)。
- 容量固定,天然防止内存无限膨胀
- 配合
AbortPolicy或CallerRunsPolicy,可优雅应对饱和(比如让调用线程自己执行任务) - 适合对延迟敏感、资源受限的场景,如网关、实时计算节点
任务优先级明确或需按特定顺序执行 → 用 PriorityBlockingQueue
无界优先队列,要求任务实现 Comparable 或传入 Comparator。注意:它不保证完全公平(相同优先级仍可能乱序),也不支持 null 元素。
立即学习“Java免费学习笔记(深入)”;
- 适合消息分级(如告警 > 日志 > 统计)、定时任务调度(按下次执行时间排序)
- 不能直接用于需要严格 FIFO 的场景;若需“优先级 + FIFO”混合,得自行封装逻辑
- 因底层是堆结构,入队/出队为 O(log n),吞吐略低于前两者
任务极短、追求极致吞吐 & 不介意饥饿 → 用 SynchronousQueue
它不存储元素——每个 put() 必须等待配对的 take(),反之亦然。本质是“手递手”传递任务。
- 常用于
Executors.newCachedThreadPool(),配合无限制线程数,实现“来一个任务启一个线程” - 零内存占用,响应极快,但若消费者(工作线程)跟不上,生产者会阻塞或触发拒绝策略
- 适合任务执行非常快、且线程创建开销可接受的场景(如 RPC 短连接处理)


















