可以使用Object.wait()和notifyAll()实现线程安全的生产者消费者模式,核心是共享对象作锁、while循环防虚假唤醒、notifyAll()确保正确唤醒对应线程。

可以用 Object.wait() 和 notifyAll() 实现线程安全的生产者消费者模式,核心是用共享对象(如队列)作为锁,配合 wait() 阻塞等待条件、notifyAll() 唤醒所有等待线程,再结合 while 循环检查条件防止虚假唤醒。
共享缓冲区需同步访问
定义一个带容量限制的队列(如 LinkedList),所有对它的读写操作必须在同步块中进行,锁对象通常就是该队列自身或显式声明的 Object lock = new Object()。不能只靠 synchronized 方法,因为生产者和消费者需要在不同条件下等待(满/空),必须手动调用 wait() 和 notifyAll()。
- 生产者入队前:检查是否已满;满则
wait(),释放锁并挂起 - 消费者出队前:检查是否为空;空则
wait(),释放锁并挂起 - 任一操作修改状态后(如 add 或 remove),都应调用
notifyAll(),通知可能受影响的另一方
必须用 while 而非 if 检查条件
wait() 可能被意外唤醒(虚假唤醒),或多个线程被唤醒后竞争失败。若用 if 判断,线程苏醒后直接执行后续逻辑,可能破坏约束(比如从空队列取元素)。正确做法是用 while 循环重检条件:
synchronized (buffer) {
while (buffer.isEmpty()) {
buffer.wait();
}
// 安全消费
}
同理,生产者也应 while (buffer.size() >= capacity)。
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
notifyAll() 比 notify() 更稳妥
虽然 notify() 只唤醒一个等待线程,看似高效,但无法保证唤醒的是对应角色(比如生产者唤醒了另一个生产者,而消费者仍在等)。用 notifyAll() 让所有等待线程重新竞争,由 while 条件筛选真正可执行的线程,逻辑更清晰、不易死锁。实际性能差异在多数场景下可忽略。
完整协作流程示例
假设共享缓冲区最大容量为 1:
- 消费者先启动,发现空 →
wait()挂起 - 生产者获得锁,放入元素,调用
notifyAll()→ 消费者被唤醒 - 消费者再次进入同步块,
while检查非空 → 开始消费,再notifyAll() - 此时若生产者正在等待(因满),它将被唤醒并尝试入队
整个过程依赖锁的释放与重入、条件的严格校验、以及全员通知机制,缺一不可。










