Java多线程-实现 生产者-消费者 模式
多线程实现生产者消费者,堆积满 100 后停止生产,消费到小于 50 后继续生产
这是一种写法,但是我觉得不太好:
- 它通过循环创建了很多的线程,每个线程只消费/生产一次
- 它使用
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步