首页 > 其他分享 >生产者与消费者的关系是什么?市场供需关系

生产者与消费者的关系是什么?市场供需关系

时间:2023-06-08 20:15:31浏览次数:23  
标签:关系 消费者 生产者 cakeShop -- 供需 蛋糕 public

前言

本文主要讲述生产者和消费者模式,文中使用通俗易懂的案例,使你更好的学习本章知识点并理解原理,做到有道无术。

一.什么是生产者和消费者模式

生产者消费者模式并不属于常见的23种设计模式的,它是Controlnet网络中特有的一种传输数据的模式,设置方便,使用安全快捷。生产者消费者模式是一种通过容器解决生产者和消费者之间强耦合问题的设计模式。

二.生活中的生产者和消费者模式

在生活中很多店铺的经营方式之一跟生产者和消费者模式很相似

1.蛋糕店

在面包和蛋糕是由糕点师在厨房中制造出来的,然后摆放在柜台中的,因柜台上的容量是有限而且消费者的消费量也是有限的原因,糕点师不会无限地在制作面包和蛋糕,当柜台摆满后,糕点师不会再继续制作,当柜台要空了或者即将要空了,糕点师就会继续制作了,糕点师不与消费的客户直接对接。这样的模式就跟设计模式中的生产者和消费者类似。

image.png

2.水果店

大部分人买水果都会去水果店或者超市买水果,水果是由果农生产出来然后经过一系列销售然后进入到水果店或者超市中,而店家会根据店铺大小和周围的消费情况来决定水果的进货。当水果滞销的时候,店家则会减少甚至不进货,而当水果热销甚至短缺的时候,店家则会进货甚至提高进货量,生产水果的果农并不与购买水果的客户直接对接。这样的模式就跟设计模式中的生产者和消费者类似。

在这里插入图片描述

3.烧烤店

在烧烤店中,老板需要提前准备好食材,如果消费人员多,食材不够,老板则会多准备食材,如果消费人员少,老板则会少准备食材,出售食材的商贩并不与到烧烤店消费的客户直接对接。这样的模式就跟设计模式中的生产者和消费者类似。

image.png

三.生产者和消费者模式的实现

接下来我们以蛋糕店举例,通过生产者和消费者模式来实现,此案例建立在多线程的基础上。首先创建一个产品类蛋糕类和一个缓冲区蛋糕店类

package com.qianfeng.ran;
/*
 * @author:江帅
 *   	产品类
 *      	蛋糕类
 */
public class Cake {
    //蛋糕名
    private String name;

    public Cake() {
    }

    public Cake(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Cake{" +
                "name='" + name + '\'' +
                '}';
    }
}



/*
 * @author:江帅
 *   	缓冲区
 *          蛋糕店
 */
class CakeShop {
    //存放蛋糕的柜台   --  存放蛋糕类对象的数组
    private Cake[] counter = new Cake[10];
    //已有蛋糕的数量   --  指针
    private int index = 0;

    //厨师把蛋糕放在柜台的行为  --  生产者存放产品的方法
    public synchronized void input(Cake cake){
        //判断柜台是否满了  --  判断数组是否已满
        while(index == counter.length){
            try {
                //让糕点师暂停制作蛋糕 --  使生产者线程进入等待
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //把蛋糕放在柜台上  --  把产品存放在数组中
        counter[index++] = cake;
        System.out.println(Thread.currentThread().getName()+"大厨制作了一个"+cake.getName()+",柜台上有"+index+"个蛋糕");
        //通知客人可以继续消费    --  唤醒消费者继续消费
        this.notifyAll();
    }

    //客户购买蛋糕的行为     --  消费者消费产品的方法
    public synchronized void outPut(){
        //判断柜台是否为空
        while (index == 0){
            try {
                //客户停止消费    --  使消费者线程进入等待
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //客户购买的蛋糕
        Cake cake = counter[--index];
        System.out.println(Thread.currentThread().getName()+"购买了一个"+cake.getName());
        //已购买的蛋糕所在柜台的位置为null
        counter[index] = null;
        //提醒所有的糕点师该继续继续制作蛋糕      --  唤醒所有的生产者
        this.notifyAll();
    }
}

再创建生产者类消费者类并且都实现 Runnable 接口

package com.qianfeng.ran;

import java.util.Random;

/*
 * @author:江帅
 *      生产者
 *          糕点师
 */
public class PastryCook implements Runnable {
    //蛋糕店对象
    private CakeShop cakeShop;
    public PastryCook(CakeShop cakeShop){
        this.cakeShop = cakeShop;
    }

    @Override
    public void run() {
        while (true){
            //制作蛋糕	--	创建蛋糕类对象
            Cake cake = makeCake();
            //存放到柜台中
            cakeShop.input(cake);
            try {
                //适当休眠
                Thread.sleep(new Random().nextInt(2000)+1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


	/**
     *  制作蛋糕            --  创建随机的蛋糕
     * @return  蛋糕类对象
     */
    private Cake makeCake() {
        String[] cakeNames = {"黑森林蛋糕","抹茶蛋糕","草莓蛋糕","水果蛋糕","青草蛋糕"};
        //随机生成蛋糕名
        String cakeName = cakeNames[(int)(Math.random()*cakeNames.length)];
        //创建蛋糕类对象并返回
        return new Cake(cakeName);
    }
}

/*
 * @author:江帅
 *      消费者
 *          人类
 */
class Human implements Runnable{
    //蛋糕店对象
    private CakeShop cakeShop;
    public Human(CakeShop cakeShop){
        this.cakeShop = cakeShop;
    }

    @Override
    public void run() {
        while(true){
            //客户购买蛋糕行为
            cakeShop.outPut();
            try {
                //适当休眠
                Thread.sleep(new Random().nextInt(3000)+2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

最后通过生产者和消费者模式来模拟用户消费和厨师生产的场景

package com.qianfeng.ran;

/*
 * @author:江帅
 *      客户端
 */
public class Demo {
    public static void main(String[] args) {
        //----------打印结果为糕点师生成蛋糕、消费者购买蛋糕的场景-------
        //---------------当蛋糕达到10个,糕点师不会继续生产------------
        //-----------------当蛋糕售空后,消费者不会再购买--------------
        //创建蛋糕店
        CakeShop cakeShop = new CakeShop();
        //创建多个糕点师并开始在蛋糕店制作蛋糕
        PastryCook pastryCook = new PastryCook(cakeShop);
        new Thread(pastryCook,"小当家").start();
        new Thread(pastryCook,"南翔").start();

        //创建多个消费者并开始在蛋糕店购买蛋糕
        Human human = new Human(cakeShop);
        new Thread(human,"江帅").start();
        new Thread(human,"Jack Ma").start();
        new Thread(human,"企鹅马").start();

    }
}

四.总结

生成者把生成的数据存放到缓冲区里,当缓冲区里不为空时需要通知消费者消费,当缓冲区满了则自己进入等待。

消费者者需要数据的时候则从缓冲区里获取,当缓冲区不为空时需要通知生产者生成,当缓冲区满了则自己进入等待。

在这个生产者与消费者模式中,生产者并不与消费者产生直接的联系。而是通过缓冲区(缓冲区)把生产者(糕点师)和消费者(客户)进行关联,使生产者和消费者的耦合度降低,达到解耦性。

下一章,我们将带大家学习钢铁侠的形成(设计模式之装饰者模式)。

标签:关系,消费者,生产者,cakeShop,--,供需,蛋糕,public
From: https://www.cnblogs.com/qian-fen/p/17467518.html

相关文章

  • 【转载】CXF spring jaxws:endpoint jaxws:server 区别 与 关系
    通过spring配置实现webservice的配置有两种,一种是jaxws:endpoint ,另外一种是jaxws:server。百度上没查到相关区别,又由于本人没有跟代码,所以又google了一下,才找到:First,theyareallfortheserversideconfiguration.Second,jaxws:endpointiscomingfromJAXWSAPI,a......
  • 墨天轮国产关系型分布式数据库榜单解读
    分布式关系型数据库概述作为数据库演进方向之一,分布式能力受到更多用户的关注。从技术架构演进来看,数据库正走过了从单机式、集中式到分布式的发展过程,目前是多种架构并存的阶段。分布式架构以其更好的存储与计算扩展能力,受到更多的关注。在墨天轮社区的中国数据库流行度排行榜上......
  • SQL 编程思想:一切皆关系
    在计算机领域有许多伟大的设计理念和思想,例如:在Unix中,一切皆文件。在面向对象的编程语言中,一切皆对象。关系数据库同样也有自己的设计思想:在SQL中,一切皆关系。关系模型关系模型(Relationalmodel)由E.F.Codd博士于1970年提出,以集合论中的关系概念为基础;无论是现实世界中的实......
  • Java语言实现生产者与消费者的消息队列模型(附源码)
    Java构建生产者与消费者之间的生产关系模型,可以理解生产者生产message,存放缓存的容器,同时消费者进行消费需求的消耗,如果做一个合理的比喻的话:生产者消费者问题是线程模型中的经典问题。解决生产者/消费者问题有两种方法:一是采用某种机制保护生产者和消费者之间的同步;二是在生产者和......
  • 显卡,CPU,GPU和CUDA的关系与区别
    (1)显卡:显卡全称显示接口卡,又称显示适配器,是计算机最基本配置、最重要的配件之一。就像电脑联网需要网卡,主机里的数据要显示在屏幕上就需要显卡。因此,显卡是电脑进行数模信号转换的设备,承担输出显示图形的任务。具体来说,显卡接在电脑主板上,它将电脑的数字信号转换成模拟信号让显示器......
  • dockerfile中ENTRYPOINT和CMD的关系
    在使用Dockerfile构建镜像时,ENTRYPOINT和CMD都可以作为容器启动时的命令,下面是两个DockerFileFROMubuntu:22.04ENTRYPOINT["echo","Hello"]CMD["World","ChatGPT"]CMD["123","ABC"]输出:Hello123ABCFROMubuntu:22.04ENT......
  • 逻辑关系
    逻辑关系:   1.转折关系:相反关系 2.顺诚关系:时间关系空间关系事理逻辑关系    3.递进(变弱或者变强)关系:范围----更小或者更大程度----更小或者耿丹语义关系更进一层   ......
  • 动态规划三:常见状态与常见递推关系式
    动态规划三:常见递推关系式常见状态坐标型前缀划分型前缀匹配型区间型背包型常见状态坐标型dp[i]:从起点到坐标i的最值/方案数/可行性dp[i][j]:从起点到坐标i,j的最值/方案数/可行性 前缀划分型dp[i]:前i个字符的最值/方案数/可行性dp[i][j]:前i个字符划分为j个部分的......
  • Makefile基础教程(自动生成依赖关系)
    @TOC前言在前面的文章中我们都只使用到了.c文件作为依赖但是在实际的工程中肯定是不可能只有.c文件的还存在.h文件,那么在包含了.h文件后又该如何来包含依赖关系呢?一、makefile不包含.h依赖的后果首先先在目录下新建四个文件夹,其中就包含了fun.h这个文件。makefile:OBJS:=fun.omai......
  • Oracle 19C组件ID、组件名称和组件全称对应关系以及dbca静默组件选择
     Oracle19C组件ID、组件名称和组件全称对应关系以及dbca静默组件选择 dbca可以调用图形化界面来创建数据库,当选择“CustomDatabase”模板的时候会出现“DatabaseOptions”来选择options安装对应组件,总共8个options。PS:在安装数据库期间,组件实际说法为options,安装数据库选......