java简单做一个消费者/生产者案例

news2024/12/29 8:47:23

首先 我们创建一个包
在包下创建
四个类
首先是奶箱类 milkBox 在业务中充当数据的存储类
参考代码如下

public class milkBox {
    private int milk;
    public void put (int milk){
        this.milk = milk;
        System.out.println("送奶工将第"+this.milk+"瓶奶放入奶箱");
    }
    public void get(){
        System.out.println("用户拿到第"+this.milk+"瓶奶");
    }
}

奶箱类 定义了一个milk公共变量 用于统计当前是第几瓶奶
提供了插入方法 put 可以改变milk的值
获取方法 get 可以实时获取当前是第几瓶奶

producer 生成者类 参考代码如下

public class producer implements Runnable {
    milkBox ma;
    public producer(milkBox ma) {
        this.ma = ma;
    }
    public void run (){
        for(int i = 1;i < 6;i++){
            ma.put(i);
        }
    }
}

这里 我们通过带参构造方法 获取了milkBox奶箱类的对象 并存储 实现了Runnable接口 可以实现线程

然后 run 方法中编写逻辑 循环调用5次奶箱类 put插入方法

消费者类 consumer 参考代码如下

public class consumer implements Runnable {
    milkBox ma;
    public consumer(milkBox ma) {
        this.ma = ma;
    }
    public void run (){
        while (true) {
            ma.get();
        }
    }
}

我们消费者类 也利用带参构造方法 获取了milkBox奶箱类的对象 也存储了起来 也实现了 Runnable 接口 说明要实现为一个线程

run 编写一个死循环 去获取 奶箱中的milk变量

text 测试类 参考代码如下

public class text {
    public static void main(String args[]) {
        milkBox ma = new milkBox();
        producer pre = new producer(ma);
        consumer cons = new consumer(ma);
        Thread p = new Thread(pre);
        Thread c = new Thread(cons);
        p.start();
        c.start();
    }
}

我们测试类 通过main 先实例化了 milkBox 奶箱类 然后实例化producer 生产者类 在实例化时 通过构造方法 将milkBox 奶箱类的对象传给了生产者类 下面对consumer消费者类的实例化也是同理

然后通过Thread将生产者 和 消费者类都实例化成了线程

最后调用 start 方法 启动线程

然后我们执行代码
因为 我们消费者类里写的是个死循环 所有 运行一段时间 要赶紧停掉
在这里插入图片描述
但把记录翻到最上面 好像用户一直在拿第五瓶奶
在这里插入图片描述
这是因为 生产者方法 执行的太快了

我们需要改造一下奶箱类里的两个数据处理方法

将 milkBox 类代码修改如下

public class milkBox {
    private int milk;
    private boolean stock;
    public synchronized void put (int milk){
        if(stock) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.milk = milk;
        System.out.println("送奶工将第"+this.milk+"瓶奶放入奶箱");
        stock = true;
    }
    public synchronized void get(){
        if(!stock) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("用户拿到第"+this.milk+"瓶奶");
        stock = false;
    }
}

首先 我们定义了一个布尔类型的变量 stock 监听奶箱里还有没有牛奶没被消费

然后 把插入 put方法 改成同步方法 因为只有这样才能用锁 然后 判断 stock如果为true 所有还没没有被消费的牛奶 那么 他就等待

stock为 false 说明 已经没有没被消费过的牛奶了 这时 我们执行 插入奶数量逻辑 执行完之后 把stock赋值为 true 告诉系统 我们新加的牛奶还没被消费过

同时 get 消费方法也被上了锁 如果 stock为 false 所有 牛奶都被消费过 我们进入等待 然后

stock为true 说明 还有牛奶没被消费 这时我们执行消费牛奶逻辑 结束后将stock改为 false 说明 牛奶都被消费过了

然后我们运行代码 效果如下

在这里插入图片描述
但这时 显然卡死了 就执行了一次 因为我们暂时只有锁定 但没有唤醒操作

将 milkBox 代码更改如下

public class milkBox {
    private int milk;
    private boolean stock;
    public synchronized void put (int milk){
        if(stock) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.milk = milk;
        System.out.println("送奶工将第"+this.milk+"瓶奶放入奶箱");
        stock = true;
        notifyAll();
    }
    public synchronized void get(){
        if(!stock) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("用户拿到第"+this.milk+"瓶奶");
        stock = false;
        notifyAll();
    }
}

我们每次 同步方法更改状态后 执行一次notifyAll 唤醒其他的线程

这样我们运行代码如下

在这里插入图片描述
就没有任何问题了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为是如何从0到1打造以项目为中心运作的项目管理体系的?

本文介绍了华为公司打破传统的功能型组织结构&#xff0c;从弱矩阵项目管理向强矩阵转变的历程。 内容包括如何全面铺设项目管理组织&#xff0c;转向“以项目为中心”。同时&#xff0c;通过一系列的政策、标准和规定统一项目管理语言&#xff0c;建设项目管理流程体系。 其…

Servlet与表单数据交互(如文本框、单选按钮、复选框、下拉列表等)

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

基于遗传算法解决TSP问题(Matlab代码实现)

目录 1 概述 2 运行结果 3 Matlab代码实现 4 结语 5 参考文献 1 概述 旅行商问题是一个经典的路径规划问题&#xff0c;传统TSP假设客户位置和客户之间旅行时间是固定不变的&#xff0c;而在现实生活中交通状况和客户要求可能会随着时间而改变&#xff0c;为了找到最经济的…

(附源码)ssm教育机构管理系统 毕业设计 010224

ssm教育机构管理系统 摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设…

被AI包裹的冬天,智慧供热打破城市供热的“不可能三角”

最近很多城市都迎来了今冬以来的最强寒潮&#xff0c;在拉尼娜事件的影响下&#xff0c;一个格外寒冷的冬天似乎不可避免。而每次降温&#xff0c;有暖气的北方城市就会引来网络上一片艳羡之声。前不久网络上就流传着一个段子“南方人的命也是命&#xff0c;请给南方装暖气 ”&…

自定义jdk镜像

启动虚拟机&#xff0c;进入centos 1.创建文件夹上传jdk的安装包,和在同级目录下编写Dockerfile文件 #创建镜像目录 mkdir –p /javaxl_docker/jdk #安装lrzsz命令 yum install lrzsz -y #选择文件进行上传 rz # 注意d是大写 touch Dockerfile 2.编写 Dockerfile 文件 #1.指定基…

使用C++实现Windows和Linux的Flutter文档扫描插件

文档扫描应用大都是移动应用。结合手机摄像头可以实现文档拍摄&#xff0c;边缘检测&#xff0c;自动剪裁&#xff0c;透视矫正&#xff0c;滤镜等功能。但是桌面办公也少不了文档处理。这里分享下如何使用Dynamsoft Document Normalizer C SDK实现用于桌面文档处理的Flutter插…

抖音最新版抓包方案,修改so绕过ssl

dy过ssl charles抓包 及xposed的justtrustme安装到手机上只能过系统的ssl。 抖音写了一个非系统的ssl所以需要反编译so来处理。 第一步&#xff0c;charles 我用的是magisk手机&#xff0c;先重charles把证书下载到pc端 选项1&#xff0c;安装证书到本地 选项2&#xff0c…

Android桌面图标快捷方式

一、背景 长按桌面图标实现快捷方式最早是iOS提供的功能,而Android最早在Android 7.1版本也提供了对这方面的支持,于是在短时间内,像微信,支付宝,头条等流量级应用都提供了这方面的支持,如下图。 现在,长按桌面图标快捷方式已经是很成熟的功能,实现上也比较简单,主…

知识图谱-KGE-语义匹配-双线性模型(打分函数用到了双线性函数)-2011:RESCAL【双线性模型的开山之作】【把每个关系对应的邻接矩阵进行了矩阵的分解】

【paper】 A Three-Way Model for Collective Learning on Multi-Relational Data 【简介】 这篇文章应该算是双线性模型的开山之作。是德国的一个团队发表在 ICML 2011 上的工作&#xff0c;比较老了&#xff0c;主要思想是三维张量分解。 想研究啥&#xff0c;啥就很重要 Re…

Activity7-流程初体验

流程符号详解&#xff1a; 创建Activiti工作流的主要步骤包含以下几步: 1. 定义流程。按照BPMN的规范&#xff0c;使用流程定义工具&#xff0c;将整个流程描述出来。 2. 部署流程。把画好的BPMN流程定义文件加载到数据库中&#xff0c;生成相关的表数据。 3. 启动流程。使用…

基于粒子群优化算法的微电网调度(光伏、储能、电动车、电网交互)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

目标检测3

还是目标检测相关~这次是Box Size置信度偏差会损害目标检测器 检测器的置信度预测在目标大小和位置方面存在偏差&#xff0c;但目前尚不清楚这种偏差与受影响的目标检测器的性能有何关系。 无数应用依赖于目标检测器的可靠置信度估计的准确预测。然而&#xff0c;众所周知&am…

[附源码]Python计算机毕业设计Django在线招聘网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

突破40%!新能源汽车L2级辅助驾驶搭载率创新高

新能源汽车正在成为智能化的主力军。 高工智能汽车研究院监测数据显示&#xff0c;2022年1-10月中国市场&#xff08;不含进出口&#xff09;新能源汽车前装标配搭载L2级辅助驾驶交付上险167.51万辆&#xff0c;前装搭载率首次突破40%&#xff0c;达到41.93%&#xff1b;同期&…

[Java反序列化]CommonsBeanutils1利用链学习

0x01 前篇shiro的利用&#xff0c;需要动态字节码 &#xff0c;而这种方式需要我们自己添加依赖&#xff0c;所以很局限&#xff0c;而CommonsBeanutils 是shiro的依赖&#xff0c; CommonsBeanutils 是应用于 javabean 的工具 javabean的定义 类必须是具体的和公共的&#…

传统服务器与云服务器

传统服务器 传统服务器即物理服务器&#xff0c;是指独立服务器&#xff0c;也就是指物理上的单独服务器&#xff0c;物理服务器的构成包括处理器、硬盘、内存、系统总线等&#xff0c;和通用的计算机架构类似。 裸机物理服务器(BMS) 裸机服务器的官方定义是&#xff1a;裸机…

【嵌入式硬件芯片开发笔记】4-2 mADAC芯片AD5421配置流程

【嵌入式硬件芯片开发笔记】4-2 mADAC芯片AD5421配置流程 16位、串行输入、环路供电、4 mA至20 mA DAC 可用于HART协议相关电路 同AD5700配合使用 AD5421的SPI和普通的不一样 回读时要发两段 CS中间拉高一次 数据在SCLK上升沿逐个输出&#xff0c;而且在 SCLK下降沿有效 固CPO…

微服务框架 SpringCloud微服务架构 26 数据聚合 26.2 DSL 实现Bucket聚合

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构26 数据聚合26.2 DSL 实现Bucket聚合26.2.1 DSL 实现Bucket聚合26.2.2 Buc…

【设计模式】享元模式(Flyweight Pattern)

享元模式属于结构型模式&#xff0c;主要解决系统需要使用大量相似对象&#xff08;细粒度对象&#xff09;而消耗大量内存资源的问题。享元模式运用共享技术有效地支持大量细粒度的对象&#xff0c;其通过提取对象共同的信息抽象出享元对象&#xff0c;实现共享功能&#xff0…