生产者消费者问题
2026/8/24大约 1 分钟
生产者消费者问题
经典并发问题:通过共享资源对象 + wait/notify 实现生产者与消费者的协作。
问题描述
多个生产者线程不断生产资源,多个消费者线程不断消费资源,共享同一份公共资源。需要保证:资源有上限、不能重复消费、线程间协作同步。
经典实现
公共资源类
public class PublicResource {
private int number = 0; // 当前资源数量
private int size = 10; // 资源上限
/** 生产者调用:生产一个资源 */
public synchronized void increase() {
while (number >= size) { // 已满,等待
try { wait(); } catch (InterruptedException e) { }
}
number++;
System.out.println("生产一个,当前:" + number);
notifyAll(); // 唤醒消费者
}
/** 消费者调用:消费一个资源 */
public synchronized void decrease() {
while (number <= 0) { // 为空,等待
try { wait(); } catch (InterruptedException e) { }
}
number--;
System.out.println("消费一个,当前:" + number);
notifyAll(); // 唤醒生产者
}
}生产者线程
public class ProducerThread implements Runnable {
private PublicResource resource;
public ProducerThread(PublicResource resource) {
this.resource = resource;
}
@Override
public void run() {
while (true) {
try { Thread.sleep((long) (Math.random() * 1000)); }
catch (InterruptedException e) { e.printStackTrace(); }
resource.increase();
}
}
}消费者线程
public class ConsumerThread implements Runnable {
private PublicResource resource;
public ConsumerThread(PublicResource resource) {
this.resource = resource;
}
@Override
public void run() {
while (true) {
try { Thread.sleep((long) (Math.random() * 1000)); }
catch (InterruptedException e) { e.printStackTrace(); }
resource.decrease();
}
}
}启动
PublicResource resource = new PublicResource();
new Thread(new ProducerThread(resource)).start();
new Thread(new ConsumerThread(resource)).start();关键点
increase()/decrease()必须用synchronized保证互斥- 用
while而非if检查条件——防止虚假唤醒,唤醒后需重新检查条件 wait()释放锁,让另一方进入notifyAll()唤醒所有等待线程,避免"只唤醒一个、且该线程因条件不满足再次等待"导致的死锁
其他实现方式
- 阻塞队列实现:使用
ArrayBlockingQueue,put()/take()自带阻塞与同步 - Lock + Condition 实现:
ReentrantLock配合Condition.await()/signal()