生产消费设计模式

来源:互联网 发布:基地组织知乎 编辑:程序博客网 时间:2024/04/27 22:20

生产消费模式

在实际的软件开发过程中,经常会碰到如下场景: 某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象的成为生产者;而处理数据的模块,就成为消费者。

单单抽象出生产者和消费者,还不够算上是生产者/消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介(类似于商店,生产者生产完供货给商店,商店卖给消费者),生产者把数据放入缓冲区,而消费者从缓冲区取出数据。

生产者消费者的关系如下图所示:

生产者消费者模式的原理描述
1. 生产者仅仅在仓储未满时候生产,仓满则停止生产。
2. 消费者仅仅在仓储有产品时候才能消费,仓空则等待生产。
3. 当消费者发现仓储没产品可消费时,会通知生产者生产。
4. 生产者在生产出可消费产品时,应该通知等待的消费者去消费。

程序实例:
1. 先创建一个库存商品管理类

public class ProductStorage {    // 最大库存    public static final int Maximum = 100;    // 当前库存量    public static int Currentimun = 50;    // 库存管理实例    private static ProductStorage instance;    private ProductStorage() {    }    // 获取单例    public static ProductStorage getInstance() {        if (instance == null) {            instance = new ProductStorage();        }        return instance;    }    // 生产产品    public synchronized void product() {        while (Currentimun >= (Maximum / 2)) {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        Currentimun++;        System.out.println("当前线程:" + Thread.currentThread().getName() + "生产了一个商品,当前库存量:" + Currentimun);        notifyAll();    }    // 消费产品    public synchronized void consume() {        while (Currentimun <= 0) {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        Currentimun--;        System.out.println("当前线程:" + Thread.currentThread().getName() + "消费了一个商品,当前库存:" + Currentimun);        notifyAll();    }}
  1. 创建商品生产者模型
//商品生产者模型public class Producter implements Runnable{    @Override    public void run() {        while(true){            try{                Thread.sleep(500);            }catch(InterruptedException e){                e.printStackTrace();            }            //调用生产方法            ProductStorage.getInstance().product();        }    }}
  1. 创建商品消费者模型
//商品消费者模型public class Consumer implements Runnable {    @Override    public void run() {        while (true) {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            //调用消费方法            ProductStorage.getInstance().consume();        }    }}
  1. 最后创建主程序 ,主程序的作用,其实就是启动线程。
public class TestProduct {    public static void main(String[] args) {        //启动线程        Producter p=new Producter();        Consumer c =new Consumer();        new Thread(p).start();        new Thread(c).start();        /*        这里代码是使用线程池来启动线程        ExecutorService pool=Executors.newFixedThreadPool(10);        pool.submit(p);        pool.submit(c);        pool.shutdown();*/    }}

生产者消费者模式的优点:
1. 将生产模块和消费模块分隔开,从而降低了程序的耦合,便于程序的扩展和维护。
2. 将生产模块和消费模块的分隔,可使生产模块的运行不再依赖消费模块的执行,由同步改为异步执行并且都可支持并发,从而大大提高了程序的效率。
3. 生产者产生的数据存放在缓冲区中,消费者可以按照自己的逻辑来取出数据处理,从而有效的避免消费模块任务执行负载不均的问题。

0 0