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 EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 如何在桌面浏览器上使用 webdriver 移动网络

    我正在使用 selenium webdriver 进行 AUT 被测应用程序 的功能测试自动化 AUT 是响应式网络 我几乎完成了桌面浏览器的不同测试用例 现在 相同的测试用例也适用于移动浏览器 因为可以从移动浏览器访问 AUT 由于它是响
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch

随机推荐

  • 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