synchronized 实现生产者消费者模型需用 sharedbuffer 封装固定容量队列,生产者满时 wait()、消费者空时 wait(),均用 while 循环防虚假唤醒,每次操作后 notifyall() 唤醒所有等待线程。

用 synchronized 实现标准的生产者消费者模型,核心是:一个共享缓冲区、两个线程角色(生产者/消费者)、使用 wait() 和 notifyAll() 配合 synchronized 块完成线程协作与状态等待。
共享缓冲区需线程安全且支持等待唤醒
定义一个固定容量的队列(如 ArrayList),所有访问必须加锁;当缓冲区满时,生产者调用 wait() 暂停;当空时,消费者同样等待。注意:必须在 synchronized 块内调用 wait() 和 notifyAll(),否则抛 IllegalMonitorStateException。
- 缓冲区封装成独立类(如
SharedBuffer),把同步逻辑收拢 - 用
while而非if判断条件,防止虚假唤醒(spurious wakeup) - 每次修改后调用
notifyAll()—— 因为无法确定该唤醒生产者还是消费者
生产者逻辑:加锁 → 满则等待 → 入队 → 唤醒
生产者不断生成数据,尝试放入缓冲区。若已满,主动释放锁并进入等待;一旦被唤醒,重新检查是否可入队。
public void produce(int item) throws InterruptedException {
synchronized (this) {
while (buffer.size() == capacity) {
wait(); // 释放锁,等待消费者消费
}
buffer.add(item);
System.out.println("Produced: " + item + ", size=" + buffer.size());
notifyAll(); // 唤醒可能等待的消费者(也可能唤醒其他生产者,但会被 while 拦住)
}
}
消费者逻辑:加锁 → 空则等待 → 出队 → 唤醒
消费者从缓冲区取数据,为空时等待;取到后通知其他等待线程。
public int consume() throws InterruptedException {
synchronized (this) {
while (buffer.isEmpty()) {
wait(); // 释放锁,等待生产者生产
}
int item = buffer.remove(0);
System.out.println("Consumed: " + item + ", remaining=" + buffer.size());
notifyAll(); // 唤醒可能等待的生产者
return item;
}
}
完整可运行示例结构
主程序启动多个生产者和消费者线程,共享同一个 SharedBuffer 实例。建议设置合理循环次数或使用守护线程控制退出,避免无限等待。
- 缓冲区容量设为较小值(如 3),便于观察等待行为
- 每个线程 sleep 随机毫秒模拟真实耗时,增强并发效果
- 不要在
wait()外层捕获InterruptedException后吞掉——应向上抛出或响应中断(如Thread.currentThread().interrupt())
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











