LinkedBlockingQueue 是线程安全、基于链表的阻塞队列,适合生产者-消费者模式,支持无界或有界容量,需合理设容防 OOM 或阻塞,配合线程池实现解耦与高吞吐,并支持优雅关闭与细粒度锁优化。

LinkedBlockingQueue 是 Java 并发包中一个线程安全、基于链表实现的阻塞队列,特别适合构建生产者-消费者模式的任务管道。它默认容量为 Integer.MAX_VALUE(无界),也可指定固定容量,配合 take() / put() 等阻塞方法,天然支持背压与流量控制,是高吞吐多线程任务管道的理想底座。
用作任务缓冲:合理设置容量避免 OOM 或过度阻塞
无界队列虽简化逻辑,但若生产速度持续高于消费速度,会导致内存耗尽;而容量过小又容易频繁阻塞生产者,降低吞吐。建议根据任务平均处理时长、峰值流量和可用堆内存估算合理容量。
- 典型做法:设为预估峰值并发任务数的 2~3 倍(如预计同时最多 1000 个待处理任务,可设 capacity = 2000)
- 初始化示例:new LinkedBlockingQueue<Runnable>(2000)
- 监控队列长度(queue.size())并告警,是线上调优的重要依据
搭配线程池:分离生产与消费逻辑,提升 CPU 利用率
不要让生产者线程直接执行耗时任务,而是只负责入队;由专用消费者线程池异步拉取并执行。这样能解耦响应延迟与业务处理,同时充分利用多核。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 推荐使用 Executors.newFixedThreadPool(n) 配合 queue,n 通常设为 CPU 核心数 × 1.5 ~ 2(IO 密集型可更高)
- 消费者线程循环调用 queue.take()(阻塞获取),避免空轮询浪费 CPU
- 异常需捕获并记录,防止单个任务失败导致整个消费线程退出
支持优雅关闭:确保未完成任务不丢失
系统停机或模块重启时,不能粗暴中断正在运行的任务。LinkedBlockingQueue 提供了 clear() 和 drainTo(),配合线程池的 shutdown + awaitTermination 可实现可控退出。
立即学习“Java免费学习笔记(深入)”;
- 先调用 executor.shutdown() 停止接收新任务
- 再用 queue.drainTo(list) 将剩余任务导出,交由备用线程或持久化存储处理
- 最后 awaitTermination(timeout, TimeUnit.SECONDS) 等待活跃任务结束
注意锁粒度与性能边界
LinkedBlockingQueue 内部使用独立的 takeLock 和 putLock,读写互不阻塞,比 ArrayBlockingQueue 的单锁设计更适合高并发场景。但在极端吞吐下(如每秒百万级操作),仍可能成为瓶颈。
- 避免在任务对象中存放大量临时数据——队列中存的是引用,对象本身仍在堆中
- 如需更高吞吐,可考虑 Disruptor 等无锁 RingBuffer,但复杂度显著上升
- JDK9+ 中可关注 TransferQueue 接口及 SynchronousQueue 的“直接交接”模式,适用于低延迟场景

















