所谓生产者-消费者问题,实际上主要是包含了两类线程,一种是生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库,生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为;而消费者只需要从共享数据区中去获取数据,就不再需要关心生产者的行为。
在实现生产者消费者问题时,可以采用三种方式:
- 使用 Object 的
wait()/notify()的消息通知机制; - 使用 Lock 的 Condition 的
await()/signal()的消息通知机制; - 使用 BlockingQueue 实现。
1、基于 Object 的 wait()/notifyAll() 实现方式
1.1 理论基础
关于 wait()、notify() 和 notifyAll() 的理论基础,可以参考笔者的文章,
《并发编程专题 2:使用多线程编程》 的 《线程控制 wait()、notify() 和 notifyAll()》 一节。
1.2 基于 Object 的 wait()/notifyAll() 生产者消费者模式
// 生产者
private static class Consumer implements Runnable {
private List<Object> products;
// 传入的对象是产品,也就是说,生产者和消费者通过产品建立联系
public Consumer(List<Object> products) {
this.products = products;
}
public void run() {
while (true) {
// 使用循环来不断消费
synchronized (products) {
// 对产品加锁 products
while (products.isEmpty()) {
// 1. 没有产品了
try {
// 调用 wait() 的时候使用 tru...catch 防止线程终端
products.wait(); // 已经没有产品可以消费了
} catch (InterruptedException e) {
e.printStackTrace();
}
}
products.remove(0); // 消费一个
products.notifyAll(); // 通知其他线程
System.out.println("Eat one. Left : " + products.size());
}
}
}
}
// 消费者
private static class Producer implements Runnable {
private final int max; // 产品的上限
private List<Object> products;
// 参数是产品的上限和产品列表(理解成仓库和仓库的最大容量亦可)
public Producer(int max, List<Object> products) {
this.max = max;
this.products = products;
}
public void run() {
while (true)

本文详细探讨了生产者消费者问题的三种实现方式:基于Object的wait()/notifyAll()、Lock的Condition以及使用BlockingQueue。在实现中,避免了假死状态并确保线程安全。使用BlockingQueue实现时,代码简洁且避免了手动线程控制。
最低0.47元/天 解锁文章
1247

被折叠的 条评论
为什么被折叠?



