700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java设计模式之生产者/消费者模式

Java设计模式之生产者/消费者模式

时间:2022-10-28 11:42:59

相关推荐

Java设计模式之生产者/消费者模式

一、什么是生产者/消费者模式?

某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。

结构图如下:

二、生产者消费者模式的优点:

1、解耦:

由于有缓冲区的存在,生产者和消费者之间不直接依赖,耦合度降低。

2、支持并发:

由于生产者与消费者是两个独立的并发体,他们之间是用缓冲区作为桥梁连接,生产者只需要往缓冲区里丢数据,就可以继续生产下一个数据,而消费者只需要从缓冲区了拿数据即可,这样就不会因为彼此的处理速度而发生阻塞。

3、支持忙闲不均:

缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来 了。当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。 等生产者的制造速度慢下来,消费者再慢慢处理掉。

三、生产者-消费者模型【即“生产者-仓储-消费者”】模型遵循的规则:

1、生产者仅仅在仓储未满时候生产,仓满则停止生产。

2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。

3、当消费者发现仓储没产品可消费时候会通知生产者生产。

4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

四、源码示例:

1、仓库:

package com.hongri.designpattern.producer_consumer;import java.util.LinkedList;/*** 仓库【即共享数据区域】*/public class SyncStack {LinkedList<Integer> list = new LinkedList<>();int capacity = 10;public volatile int index;/*** 供生产者调用** @param value*/public synchronized void push(String producerName, int value) {while (list.size() >= capacity) {try {System.out.println("仓库已满 ---> 生产者--进入wait状态");wait();} catch (InterruptedException e) {e.printStackTrace();}}//没有满,则继续produceSystem.out.println("生产者--" + producerName + "--生产了:" + value);list.add(value);//唤醒其他所有处于wait()的线程,包括消费者和生产者notifyAll();}/*** 供消费者调用** @return*/public synchronized int pop(String consumerName) {int val = 0;while (list.size() == 0) {try {System.out.println(" 仓库无货 ---> 消费者--进入wait状态");wait();} catch (InterruptedException e) {e.printStackTrace();}}//如果有数据,继续consumeval = list.removeFirst();System.out.println(" 消费者------" + consumerName + "--消费了:" + val);notifyAll();return val;}}

2、生产者:

package com.hongri.designpattern.producer_consumer;import java.util.Random;/*** 生产者*/public class Producer implements Runnable {private String name;private SyncStack stack;public Producer(String name, SyncStack stack) {this.name = name;this.stack = stack;}@Overridepublic void run() {while (true) {int value = new Random().nextInt(100);stack.push(name, value);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}}

3、消费者:

package com.hongri.designpattern.producer_consumer;/*** 消费者*/public class Consumer implements Runnable{private String name;private SyncStack stack;public Consumer(String name, SyncStack stack) {this.name = name;this.stack = stack;}@Overridepublic void run() {while (true) {try {Thread.sleep(3000);int val = stack.pop(name);} catch (InterruptedException e) {e.printStackTrace();}}}}

4、调用:

SyncStack stack = new SyncStack();Producer producer1 = new Producer("Producer1", stack);Producer producer2 = new Producer("Producer2", stack);Producer producer3 = new Producer("Producer3", stack);Consumer consumer1 = new Consumer("Consumer1", stack);Consumer consumer2 = new Consumer("Consumer2", stack);Consumer consumer3 = new Consumer("Consumer3", stack);new Thread(producer1).start();new Thread(producer2).start();new Thread(producer3).start();new Thread(consumer1).start();new Thread(consumer2).start();new Thread(consumer3).start();

测试结果:

参考:

Java设计模式综述

生产者消费者设计模式在线程池中的应用

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。