生产消费设计模式

生产消费模式

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

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

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

生产者消费者模式的原理描述
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值