java中实现生产者消费者模型最推荐使用java.util.concurrent包的blockingqueue(如arrayblockingqueue),因其内置线程安全与阻塞逻辑,生产者调用put()、消费者调用take()即可自动阻塞等待,无需手动同步;手动实现仅用于理解原理,建议避免在生产环境直接手写。

Java 中实现生产者消费者模型,核心是解决线程间协作与资源竞争问题。最推荐的方式是使用 java.util.concurrent 包中已封装好的线程安全阻塞队列(如 ArrayBlockingQueue、LinkedBlockingQueue),配合 wait/notify 或 Lock + Condition 手动实现仅作理解参考,不建议在生产环境直接手写。
用 BlockingQueue 实现最简洁安全的生产者消费者
阻塞队列本身已内置线程安全和阻塞逻辑,无需额外同步,代码清晰且不易出错:
-
生产者调用
put():队列满时自动阻塞,直到有空间; -
消费者调用
take():队列空时自动阻塞,直到有元素; - 所有操作原子、可见、可重入,底层基于
ReentrantLock和Condition实现。
示例片段:
BlockingQueue<string> queue = new ArrayBlockingQueue(10);
// 生产者
new Thread(() -> {
for (int i = 0; i {
for (int i = 0; i
</string>
手动实现(Lock + Condition)——理解底层原理
若需自定义等待条件(例如多类型消费者),可用 ReentrantLock 配合多个 Condition:
- 一个
Lock控制临界区; -
notFull条件用于生产者等待队列不满; -
notEmpty条件用于消费者等待队列不空; - 每次
signal()唤醒对应等待线程,比notifyAll()更精准高效。
注意:必须用 while 循环判断条件(防止虚假唤醒),且 await() 必须在 lock() 后、unlock() 前调用。
避免常见陷阱
-
别用
ArrayList+synchronized模拟队列:无法阻塞,只能轮询或加休眠,浪费 CPU; -
不用
wait/notify直接操作对象锁:易因锁对象不一致、未在 synchronized 块中调用而抛IllegalMonitorStateException; -
中断处理要响应:捕获
InterruptedException后应恢复中断状态(interrupt()),而非吞掉; -
容量边界要明确:固定大小队列选
ArrayBlockingQueue,无界慎用LinkedBlockingQueue(默认 Integer.MAX_VALUE,仍可能 OOM)。
选型建议:按场景挑队列
-
强公平性要求 → 用
ArrayBlockingQueue(构造时传true开启公平锁); -
高吞吐、低延迟 →
LinkedBlockingQueue(内部双锁,生产和消费可并行); -
实时性优先、允许丢弃 →
PriorityBlockingQueue或带超时的offer(e, timeout, unit)/poll(timeout, unit); -
多生产者多消费者且需分组通知 → 自定义
Lock + N Condition。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











