Java模拟生产者消费者模型【仅代码 + 注释】

2023-05-16

模拟仓库容量为1,1个消费者,1个生产者的生产者消费者模型

package com.cskaoyan.sync;
/***
 * 模拟生产者消费者模型
 * 仓库容量为1
 * 1个消费者,1个生产者的消费者生产者模型
 */

public class Demo3 {
    public static void main(String[] args) {
        //创建仓库对象,仓库对象是被生产者和消费者共享的
        Warehouse warehouse = new Warehouse();
        //创建生产者和消费者线程
        new Thread(new Producer(warehouse),"生产者").start();
        new Thread(new Consumer(warehouse),"消费者").start();
    }
}

//生产者模型
class Producer implements Runnable{
    //生产者持有仓库对象的引用作为成员变量,方便生产手机
    private final Warehouse warehouse;

    //手机数组
    private static Phone[] phones = {
            new Phone("iphone xr",4800),
            new Phone("huawei p9",2000),
            new Phone("xiaomi",2000),
            new Phone("meizu",1000),
    };

    //私有方法,用来选择手机
    private Phone producePhone(){
        //Math.random()的取值范围:[0,1)
        return phones[(int) (Math.random() * phones.length)];
    }

    //构造器
    public Producer(Warehouse warehouse) {
        this.warehouse = warehouse;
    }

    //重写run方法
    @Override
    public void run() {
        //生产者需要先判断仓库里有没有手机
        //如果有(仓库非空),生产者阻塞
        //如果没有(仓库为空),直接生产,之后唤醒消费者进行消费手机
        //使用同步锁
        synchronized (warehouse){
            while (true){
                if (warehouse.isEmpty()){
                    //仓库为空
                    //生产手机
                    Phone phone = producePhone();
                    //放入仓库
                    warehouse.pullPhone(phone);
                    //唤醒消费者
                    warehouse.notify();
                }else {
                    try {
                        //生产者阻塞
                        warehouse.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

//消费者模型
class Consumer implements Runnable{
    //消费者持有仓库对象的引用作为成员变量,方便消费手机
    private final Warehouse warehouse;

    //构造器
    public Consumer(Warehouse warehouse) {
        this.warehouse = warehouse;
    }

    //实现Runnable接口,重写run方法
    @Override
    public void run() {
        //消费者先判断仓库里有没有手机
        //如果有的话,可以直接消费,然后唤醒生产者进程
        //如果没有的话(仓库为空),需要阻塞
        //(重点)用仓库当锁
        synchronized (warehouse){
            while (true){
                if (warehouse.isEmpty()){
                    //仓库为空
                    try {
                        warehouse.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    //仓库非空
                    warehouse.sellPhone();
                    //消费一部手机之后唤醒生产者进行手机的生产
                    warehouse.notify();
                }
            }
        }
    }
}

class Phone{
    private String name;
    private double price;

    //构造器
    public Phone(String name, double price) {
        this.name = name;
        this.price = price;
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Phone{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

//仓库
class Warehouse{
    //用于被消费者和生产者进行操作的对象
    //生产者给它赋值对象,消费者给他赋值null
    private Phone phone;

    //生产者生产手机
    public void pullPhone(Phone phone){
        //只有this.phone是成员变量,形参中和方法体里面的phone都是生产者生产的
        //把生产者生产的phone存入仓库
        this.phone = phone;
        System.out.println(Thread.currentThread().getName() + "生产了一部" + phone + "手机");
    }

    //消费者消费手机
    public void sellPhone(){
        //将仓库里的phone保存下来
        Phone sellphone = phone;
        //消费手机(清空仓库)
        phone = null;
        System.out.println(Thread.currentThread().getName() + "消费了一部" + sellphone + "手机" );
    }

    //判断仓库里有无手机,有手机返回fasle,没有手机返回true
    public boolean isEmpty(){
        return phone == null;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java模拟生产者消费者模型【仅代码 + 注释】 的相关文章

  • Java NIO Pipe 与 BlockingQueue

    我刚刚发现它只有一个 NIO 工具 即 Java NIO Pipe 它是为在线程之间传递数据而设计的 与通过队列 例如 ArrayBlockingQueue 传递的更传统的消息相比 使用此机制是否有任何优势 通常 将数据传递给另一个线程进行
  • 文件写入器覆盖文件而不是附加到末尾时出现问题

    好的 我在将多行写入文本文件时遇到一些问题 程序运行 但不会每次都使用新行 当我希望它运行 4 次时 文本文件应如下所示 a b c d 相反 它看起来像 d 谁知道如何解决这个问题 所有导入均正确导入 来源 已稍加编辑 假设一切都已正确定
  • Zuul不转发请求到其他微服务

    我正在使用 Spring Boot 微服务 我已经配置了 eureka zuul 代理和另一个微服务 帐户 如果我直接从帐户拨打电话 则工作正常 帐户和 zuul 服务器都显示在 eureka 上 当我尝试使用 zuul 代理进行访问时 它
  • JaxB2Marshaller 未将 XML 绑定到 Kotlin 数据类

    我正在编写一个批处理作业来解析 XML 提取字段并将它们保存在数据库中 解析 XML 时 它会选取 2 个根元素 但将所有字段保留为空 因此在我的数据库中 我有 2 条记录将为空字段 似乎无法弄清楚为什么它无法读取元素 TIA Bean f
  • Java 中具有级别顺序插入的完整二叉搜索树

    我们接到一个任务 需要编码 二叉搜索树 那个树has to be complete not perfect 这意味着所有不在最低级别或次低级别的节点都应该有 2 个子节点 而最低级别的节点应尽可能远离左侧 我们需要插入到树中等级顺序 所以如
  • 通过蓝牙将字符串从作为客户端的 PC 发送到作为服务器的移动设备

    我需要通过蓝牙将字符串从 PC 传输到 Android 移动设备的帮助 Android 移动设备应充当服务器并在设备屏幕上显示字符串消息 作为客户端的 PC 应该将字符串发送到移动设备 我希望服务器对提取的字符串 通过蓝牙传输 做出反应 这
  • 高负载应用程序的数据库可扩展性?

    我见过一些应用程序拥有集群 Web 服务器 例如 10 到 20 个服务器 以具有可扩展性 可以在其中分发 在网络服务器之间加载 但我总是看到所有网络服务器都使用单个数据库 现在考虑任何电子商务或铁路 Web 应用程序 其中有数百万用户在任
  • 请放心,如何在 POST 请求后从响应正文中提取生成的令牌并将其设置到标头

    执行任何请求 我需要执行身份验证POST请求正文 username somename password somepass 标头Content Type application json这给了我一个带有生成令牌的响应 我需要将其粘贴为第二个标
  • 从java应用程序发送电子邮件时出现异常:中继被拒绝

    我们正在使用 Spring Mail 从 java 应用程序发送电子邮件 org springframework mail javamail JavaMailSenderImpl Spring电子邮件配置是
  • Java Swing 自定义形状(2D 图形)

    我需要绘制自定义形状 现在 当用户单击面板上的几个点时 我使用多边形创建一个形状 public void mouseClicked MouseEvent e polygon addPoint e getX e getY repaint 但我
  • 使用 Windows 锁定屏幕后删除 Kerberos 缓存票证

    无论如何 有没有办法阻止 Kerberos 缓存的票证在 Windows 进入锁定屏幕后被删除 首次登录 Windows 时 klist exe 显示 2 个缓存票证 但是 发生 Windows 锁屏事件后 klist exe 显示 0 个
  • 在 Retrofit 中的 POST 请求中发送空正文

    我的 api 需要一个空的 json 主体 发出帖子请求时 如何在 Retrofit 和 Jackson 中进行设置 我尝试通过null 和空字符串 以及 但无法让它发挥作用 POST my url Call
  • 使用 JNDI 添加 LDAP 条目

    我正在尝试使用 JNDI 将条目添加到 LDAP 服务器 我可以成功地从 LDAP 服务器读取条目 但是当我尝试添加新条目时出现错误 我检查了各种方法但都失败了 private String getUserAttribs String se
  • 错误:找不到符号 ArrayList

    我正在尝试创建某种列表来存储数组 表 中的值 我在这里使用数组列表 但我应该使用列表吗 但是 每次我尝试编译时 它都会引发以下错误 找不到标志 符号 ArrayList类 位置 玩家类 TablePlayer 代码如下 public cla
  • 用 Java 编写“漂亮”代码的标准? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • JavaFX颜色选择器的语言

    有没有办法改变语言ColorPicker的文本 例如 自定义颜色 当前颜色 新颜色 色相 饱和度 亮度 不透明度 保存 使用 取消 编辑 以下答案适合那些需要更多内容的人exotic语言 如果您使用其中之一 de es fr it ja k
  • 在 Android 版 ORMLite 中加入类会引发 SQL 异常:找不到外部类,反之亦然

    我正在尝试使用 QueryBuilder 为两个不同的类创建一个联接查询 一个Product类和一个Coupon类 引用 Product 属性 storeId public class Coupon DatabaseField column
  • 如何从项目文件夹中的 jlabel 上设置图像?

    我正在尝试制作一个 Java 桌面应用程序 我想设置一个图像JLabel 我正在使用 NetBeans 从我的项目文件夹中 我的目录结构是 F gt MARKET src lib src defaultpackage demo java i
  • 应用程序中 GC 长时间暂停

    我当前运行的应用程序需要最大堆大小为 16GB 目前我使用以下标志来处理垃圾收集 XX UseParNewGC XX UseConcMarkSweepGC XX CMSInitiatingOccupancyFraction 50 XX Di
  • JVM锯齿状空闲进程

    我目前正在进行一项涉及 JVM 及其内存使用工作原理的研究 我不明白的是 JVM在空闲时用什么填充它的内存 只是为了在堆几乎达到时释放它 为什么使用的内存不只有一条平线 顺便说一句 这个 java 应用程序托管在 glassfish 上 但

随机推荐

  • idea 创建Spring第一个项目

    1 知道什么是maven 网上一般说maven是一个构建工具 xff0c 其实是说得很准确的 xff0c 不过我觉得更准确的说法应该是一个自动化的构建工具 你可以这样说 xff1a 不用maven的时候所有的jar都不是你家的 xff0c
  • anconda 安装dlib

    pip install CMake pip install Boost 前面两个不知道有没有用 xff0c 我是直接安装了 pip install dlib 会直接报错 xff0c 所以要到网上下载whl文件来安装 xff0c 就可以了 用
  • nodejs学习五:sequelize数据库查询的Op方法

    span class token comment 查找users表数据name span span class token keyword const span op span class token operator span model
  • 使用diskpart修复EFI分区变主分区的问题

    diskgenius有时操作EFI分区会把EFI变成主分区 xff0c 太弱智了 xff0c 呵呵 xff0c 但是这个EFI分区本身有可能会变成主分区 xff0c 这样的话系统就无法识别了 xff0c Win8 1系统的diskpart可
  • 程序员会设计后是一种什么样的感觉

    我是一个iOS开发的程序员 xff0c 也是一个自由职业者 平时靠接一些外包和做自己的产品为生 做了这么多年 xff0c 给我的感觉是 xff1a 如果你只会写程序 xff0c 那么做自由职业者的空间要小很多 01 我为什么要学设计 做自己
  • win10笔记本使用virtualbox鼠标失灵

    win10笔记本使用virtualbox6时 xff0c 发现鼠标移动偏差极大 xff0c 完全无法操作虚拟机 解决方法 xff1a 虚拟机设置中将指点设备切换为USB触控板 xff0c 运行虚拟机后右下角鼠标处右键 xff0c 勾选鼠标集
  • SpringMVC的常用注解

    SpringMVC的常用注解 1 64 Controller 64 Controller 用于标记在一个类上 xff0c 使用它标记的类就是一个SpringMVC Controller 对象 2 64 RequestMapping 用于处理
  • Hive学习之修改表、分区、列

    修改表的语句允许改变现有表的结构 通过该语句可以增加列 分区 修改SerDe 增加表和SerDe的属性或者重命名表 与之类似 修改分区的语句可以改变指定分区的属性 重命名表 重命名表的语句如下 ALTER TABLE table name
  • sftp通过秘钥上传,修改文件

    sftp是通过openssh与服务端建立连接的 xff0c 默认端口为22 1 新建一个sftp的用户 xff0c 这里就叫sftp useradd span class hljs operator s span sbin nologin
  • 说说win32 控制台应用程序、win32 项目、mfc项目、空项目那些事儿

    首先 xff0c 说一下空项目 xff0c 大多数想单纯创建c 43 43 工程的新同学 xff0c 打开vs后很可能不知道选择创建什么工程 xff0c 这时候请相信我 xff0c 空项目是你最好的选择 因为空工程不包含任何的源代码文件 x
  • Docker常用命令,使用脚本在线或者离线安装Docker

    查看 停止 删除container 查看运行的容器 docker ps 查看所有容器 docker ps a 查看所有容器id docker ps aq 先停止运行container xff0c 再删除container xff0c 再删除
  • Spring配置数据源(XML)

    1 数据源 xff08 连接池 xff09 的作用 数据源 连接池 是提高程序性能如出现的 事先实例化数据源 xff0c 初始化部分连接资源 使用连接资源时从数据源中获取 使用完毕后将连接资源归还给数据源 常见的数据源 连接池 xff1a
  • Python开发GUI工具介绍,实战:将图片转化为素描画!

    阳光普照好刺眼 7月华为云社区与csdn联合举办了黑马程序员的征文活动 xff0c 由于规则简单 xff08 保证原创文章 内容为技术类为主 且文章篇幅1000字 43 即可 xff09 xff0c 所以兴高采烈的参加了活动 本来是抱着打酱
  • spring boot配置加载不出来?

    新建一个项目发现不能用 xff0c maven依赖加载不出来 xff0c 问题界面如下 xff1a 可以明确是maven依赖出了问题 xff0c 检查配置 1 xff09 检查本地仓库是否配置正确 xff1a span class toke
  • iOS NSAttributedString(属性字符串)

    NSAttributedString实际上就是一个字符串和一本字典 字典包含每一个字符的属性 xff1a 包括字体 大小 下划线 颜色等等 关键是要知道字典中每个key的含义以及相应value的取值范围 Character Attribut
  • 无人机姿态解算_互补滤波(1)

    一 基础知识 1 坐标系 xff1a 遵循右手定则 1 1 大地坐标系 xff08 地球坐标系 xff09 xff1a 北 xff08 x轴 xff09 东 xff08 y轴 xff09 地 xff08 z轴 xff09 xff0c 地就是
  • 学会 Go 中的时间处理

    作为程序员 xff0c 我们经常需要对时间进行处理 在 Go 中 xff0c 标准库 time 提供了对应的能力 本文将介绍 time 库中一些重要的函数和方法 xff0c 希望能帮助到那些一遇到 Go 时间处理问题就需要百度的童鞋 应对时
  • Ubuntu修改文件权限

    Linux内的一切皆文件 xff0c 所以对于Linux下文件的管理就十分的重要了 Linux下的文件权限分为三种 xff1a r xff08 读 xff09 xff0c w xff08 写 xff09 xff0c x xff08 执行 x
  • Libnet简单学习

    简单了解后 xff0c 建议直接查看源码 xff0c 以获得其他函数 xff1a libnet libnet functions h File Reference 本文仅列举个别常用函数 libnet工作流程 xff08 1 xff09 通
  • Java模拟生产者消费者模型【仅代码 + 注释】

    模拟仓库容量为1 xff0c 1个消费者 xff0c 1个生产者的生产者消费者模型 span class token keyword package span span class token namespace com span clas