2023-08-28 13:51阅读: 111评论: 0推荐: 0

Java多线程-实现 生产者-消费者 模式

多线程实现生产者消费者,堆积满 100 后停止生产,消费到小于 50 后继续生产

这是一种写法,但是我觉得不太好:

  1. 它通过循环创建了很多的线程,每个线程只消费/生产一次
  2. 它使用notifyAll()通知所有的线程唤醒,包括生产者和消费者,感觉产品数量永远也达不到 50
public class Producer implements Runnable {
private final Queue<Product> queue;
private final int maxCapacity;
public Producer(Queue<Product> queue, int maxCapacity) {
this.queue = queue;
this.maxCapacity = maxCapacity;
}
@Override
public void run() {
synchronized (queue) {
while (queue.size() == maxCapacity) { //一定要用 while,而不是 if,下文解释
try {
System.out.println("生产者" + Thread.currentThread().getName() + "等待中... Queue 已达到最大容量,无法生产");
queue.wait();
System.out.println("生产者" + Thread.currentThread().getName() + "退出等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = new Random().nextInt();
queue.offer(new Product("产品" + i));
System.out.println("生产者" + Thread.currentThread().getName() + "生产了产品:" + i);
queue.notifyAll();// 通知消费者消费
}
}
}
public class Consumer implements Runnable {
private final Queue<Product> queue;
private final int minCapacity;
public Consumer(Queue<Product> queue, int minCapacity) {
this.queue = queue;
this.minCapacity = minCapacity;
}
@Override
public void run() {
synchronized (queue) {
while (queue.isEmpty()) {
try {
System.out.println("消费者" + Thread.currentThread().getName() + "等待中... Queue 已缺货,无法消费");
queue.wait();
System.out.println("消费者" + Thread.currentThread().getName() + "退出等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Product product = queue.poll();
System.out.println("消费者" + Thread.currentThread().getName() + "消费了:" + product.getName());
if (queue.size() < minCapacity) queue.notifyAll();// 库存小于50,通知生产者生产
}
}
}
public static void main(String[] args) {
Queue<Product> queue = new ArrayDeque<>();
for (int i = 0; i < 100; i++) {
new Thread(new Producer(queue, 100)).start();
new Thread(new Consumer(queue, 50)).start();
}
}

第二种:抽象出缓冲队列

public class Buffer {
private final int maxCapacity;
private final int minCapacity;
Queue<Product> buffer;
public Buffer(int maxCapacity, int minCapacity, Queue<Product> buffer) {
this.maxCapacity = maxCapacity;
this.minCapacity = minCapacity;
this.buffer = buffer;
}
public synchronized void push(Product product){
if(buffer.size()==maxCapacity){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
buffer.offer(product);
}
public synchronized Product pop(){
if(buffer.size()<minCapacity){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
return buffer.poll();
}
}
public class Producer implements Runnable {
Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
for(int i = 0;i<200;i++){
Product product = new Product(String.valueOf(i));
buffer.push(product);
System.out.println("生产了:"+i);
}
}
}
public class Consumer implements Runnable {
Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
for(int i =0;i<200;i++){
Product product = this.buffer.pop();
System.out.println("消费了:"+product.getName());
}
}
}
public static void main(String[] args) {
Buffer buffer = new Buffer(100,50,new ArrayDeque<>());
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
}

这一版中只有一个生产者和消费者线程,它们分别负责生产多个产品

而多线陈控制,对产品数量的管理都交给了抽象出的缓冲队列

本文作者:YaosGHC

本文链接:https://www.cnblogs.com/yaocy/p/17662110.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(111)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起