Java中生产者消费者模式需用synchronized块内wait()/notifyAll()协调,while循环防虚假唤醒,共享缓冲区封装满/空条件,推荐使用ArrayBlockingQueue等并发工具类。

Java 中通过 wait() 和 notify() 实现生产者消费者模式,核心是利用对象锁的等待/唤醒机制协调线程对共享缓冲区的访问。关键点在于:必须在同步块(synchronized)中调用、使用 while 而非 if 判断条件、正确配对 notify() 与 notifyAll()。
共享缓冲区需加锁并封装状态判断
定义一个线程安全的容器(如固定大小的队列),所有读写操作必须包裹在 synchronized 块中。缓冲区要明确两个条件:
- 生产者等待条件:缓冲区已满(
queue.size() == capacity) - 消费者等待条件:缓冲区为空(
queue.isEmpty())
每次操作前用 while 循环检查条件,防止虚假唤醒或条件突变。
生产者线程:先等再放再通知
生产者逻辑如下:
立即学习“Java免费学习笔记(深入)”;
- 进入同步块(锁住共享缓冲区对象)
-
while (buffer.isFull()) buffer.wait();—— 满则等待 - 放入数据:
buffer.add(item); -
buffer.notifyAll();—— 唤醒所有等待线程(推荐,避免信号丢失)
消费者线程:先等再取再通知
消费者逻辑类似:
- 进入同步块(锁同一对象)
-
while (buffer.isEmpty()) buffer.wait();—— 空则等待 - 取出数据:
item = buffer.remove(); -
buffer.notifyAll();—— 唤醒可能等待的生产者
注意:不能用 notify() 替代 notifyAll(),否则多个生产者/消费者共存时易导致部分线程永久阻塞。
完整示例的关键细节
以 BlockingQueue 简化版为例:
- 同步锁对象统一用
this或显式锁对象(如private final Object lock = new Object();) -
wait()必须在循环中,且捕获InterruptedException并恢复中断状态(Thread.currentThread().interrupt();) - 不建议继承
Thread,优先用Runnable+Thread构造,便于复用
这种实现虽底层清晰,但实际开发更推荐 java.util.concurrent 包中的 ArrayBlockingQueue 或 LinkedBlockingQueue,它们已做充分优化和异常处理。


















