一分钟彻底掌握Java多线程生产者与消费者模型

代码

package com.example.KFC;  
public class Cooker extends Thread {  public void run() {  while (true) {  synchronized (Desk.lock) {  if (Desk.maxCount == 0) {  break;  } else {  if (!Desk.flag) {  System.out.println("Cooker makes a hamburger");  Desk.flag = true;  Desk.lock.notifyAll();  } else {  try {  Desk.lock.wait();  } catch (InterruptedException e) {  throw new RuntimeException(e);  }  }  }  }  }  }  
}
package com.example.KFC;  
public class Foodie extends Thread {  public void run() {  while (true) {  synchronized (Desk.lock) {  if (Desk.maxCount == 0) {  System.out.println("Foodie is out of food");  break;  } else {  if (Desk.flag) {  Desk.maxCount--;  System.out.println("Foodie eats a hamburger and have " + Desk.maxCount + " hamburger to eat left");  Desk.flag = false;  Desk.lock.notifyAll();  } else {  try {  Desk.lock.wait();  } catch (InterruptedException e) {  throw new RuntimeException(e);  }  }  }  }  }  }  
}
package com.example.KFC;  
public class Desk {  public static boolean flag = false;  public static int maxCount = 10;  static Object lock = new Object();  
}
package com.example.KFC;  
public class Demo {  public static void main(String[] args) {  Foodie f = new Foodie();  Cooker c = new Cooker();  f.start();  c.start();  }  
}

背景介绍

这四个程序是一个简单的生产者消费者模型的实现,用于模拟厨师(生产者)制作汉堡,食客(消费者)吃汉堡的过程。
Desk.java:这是一个共享资源类,包含了一个标志位flag,一个最大计数器maxCount和一个锁对象lock。flag用于标记是否有汉堡可供食客吃,maxCount用于记录还剩下多少汉堡,lock用于同步厨师和食客的行为。
Cooker.java:这是厨师类,继承了Thread类。在其run方法中,厨师会不断地制作汉堡,直到maxCount为0。如果flag为false,表示没有汉堡,厨师就会制作一个汉堡,并将flag设为true,然后唤醒所有在lock上等待的线程(即食客)。如果flag为true,表示有汉堡,厨师就会在lock上等待。
Foodie.java:这是食客类,也继承了Thread类。在其run方法中,食客会不断地吃汉堡,直到maxCount为0。如果flag为true,表示有汉堡,食客就会吃掉一个汉堡,并将flag设为false,然后唤醒所有在lock上等待的线程(即厨师)。如果flag为false,表示没有汉堡,食客就会在lock上等待。
Demo.java:这是主程序类,创建了一个厨师线程和一个食客线程,并启动它们。
这四个程序共同模拟了一个生产者消费者问题的解决方案,通过wait和notifyAll方法以及同步块来保证厨师和食客的行为的同步性,避免了资源的浪费和冲突。

流程解读

线程的生命周期
一个“锁”上的多个线程在同一时间只能有一个处于运行态;

在本案例中,吃货和厨师在start后进入就绪态,随后吃货进入运行态,厨师在就绪态“排队”,随后吃货在run中notifyAll,随后他通过wait进入等待态,在就绪态准备的厨师进入运行态,执行厨师进程的run,在对Desk执行完方法后notiFyAll唤醒吃货使其进入就绪态排队,随后厨师通过wait进入等待态,在就绪态准备的吃货进入运行态,如此周而复始,一直到共享数据结束。

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

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

相关文章

unity中使用commandbuffer将自定义画面渲染到主相机上

CommandBuffer 保存渲染命令列表(例如设置渲染目标或绘制给定网格)。您可以指示 Unity 在内置渲染管线中的各个点安排和执行这些命令,因此,您可以自定义和扩展 Unity 的渲染功能。 这句话意味着你可以通过command buffer让相机渲…

计算机基础知识——面向对象:封装+继承+多态整理

面向对象三大特性:封装、继承、多态。 1.封装 将一系列相关事物的共同的属性和行为提取出来,放到一个类中,同时隐藏对象的属性和实现细节,仅对外提供公共的访问方式。 【JavaBean类就可以看作是封装的完美案例。】 setter和get…

001 线性查找

文章目录 迭代器主程序 迭代器 -- 定义一个名为 linearSearch 的函数,它接受两个参数:data(一个数组)和 target(一个目标值) function linearSearch(data, target) -- 使用 for 循环遍历数组 data&…

云动态摘要 2024-06-25

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新产品更新 Web应用防火墙 - 验证码支持微信小程序接入 阿里云 2024-06-25 支持客户从微信小程序场景下接入,提供人机识别的安全防护。 工业数字模型驱动引擎 - iDME控制台换新升级 华为云…

Hadoop 面试题(九)

1. 简述下面关于Hadoop系统中使用CombineFileInputFormat解决小文件问题的描述错误的是() ? A:CombineFileInputFormat是使用Hadoop API(抽象类CombineFileInputFormat)来解决小文件的问题 B:抽象类CombineFileInputF…

[20] Opencv_CUDA应用之 关键点检测器和描述符

Opencv_CUDA应用之 关键点检测器和描述符 本节中会介绍找到局部特征的各种方法,也被称为关键点检测器关键点(key-point)是表征图像的特征点,可用于准确定义对象 1. 加速段测试特征功能检测器 FAST算法用于检测角点作为图像的关键点,通过对…

轻松掌握:工科生如何高效阅读国际期刊和撰写论文(上)

⭐️我叫忆_恒心,一名喜欢书写博客的研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支…

C++使用Spdlog异步日志

Head-only库 #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE //为了使用源码函数行号等符号用的 #include "spdlog/spdlog.h" #include "spdlog/async.h" #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/rotatin…

七天速通javaSE:第三天 程序控制结构:练习题

文章目录 前言一、基础1.计算从0~100之间奇数之和和偶数之和2. 用for循环输出0~1000之间能被5整除的数,每行输出三个 二、进阶1. 九九乘法表2.等边三角形 前言 本文主要讲解三种基本程序控制结构的练习题,以期熟练掌握顺序、选择、循环三种基本结构 一、…

怎么用Python接口发送推广短信

群发短信平台推广,有不少优点。其中通过正规106运营商平台推送,信息更加正规性。尤其是对接接口短信,比如验证码之类的,个人手机号码下发的验证码一般都不靠谱。 支持点对点一对一群发,方便工资条、物业通知等变量信息…

Android开发系列(十)Jetpack Compose之Card

Card是一种常用的UI组件,用于显示一个具有卡片样式的容器。Card组件通常用于显示列表项、卡片式布局或任何需要显示边框和阴影的UI元素。 使用Card组件,您可以轻松地创建带有卡片效果的UI元素。以下是一些Card组件的常见属性和功能: elevati…

【vuejs】$forceUpdate 的使用和讲解

1. $forceUpdate 概述 forceUpdate是Vue实例的一个内置方法,用于强制Vue组件重新渲染。通常情况下,Vue的响应式系统能够自动检测到数据的变化并更新DOM,但在某些特定情况下,可能需要手动触发重新渲染,$forceUpdate方法…

YOLOv5改进(七)--改进损失函数EIoU、Alpha-IoU、SIoU、Focal-EIOU

文章目录 1、前言2、损失函数代码实现2.1、修改metrics.py2.2、修改loss.py 3、替换EIOU4、替换SIoU5、替换Alpha-IoU6、替换Focal-EIOU7、目标检测系列文章 1、前言 YOLOv5默认使用损失函数为CIoU,本文主要针对损失函数进行修改,主要将bbox_iou函数进行…

云渲染农场使用指南:如何以最低成本享受最快渲染速度?

​云渲染农场怎么低成本享受快速渲染? 云渲染农场利用其分布式计算能力,为视觉艺术家提供了一种经济高效的渲染选择。它特别适用于高质量的影视动画和视觉效果制作。下面一起来看看如何以最低的成本实现快速渲染的策略。 在追求成本效益的同时&#xff…

第一百二十七节 Java面向对象设计 - Java枚举方法

Java面向对象设计 - Java枚举方法 因为枚举类型实际上是一个类类型,所以我们可以在枚举类型体中声明一切,我们可以在类体中声明它。 以下代码使用字段,构造函数和方法定义了一个级别枚举。 public enum Level {LOW(30), MEDIUM(15), HIGH(7…

2024年好用的加密工具,迅软DSE加密系统原来这么强大

加密软件具有灵活的加密方式和用户友好的操作界面,可定制个性化的安全方案,同时支持数据备份和恢复功能,确保数据的完整性和可用性,是保护数据安全、维护商业机密、防范信息泄露的重要工具。 2024好用的加密工具是哪个&#xff1f…

云计算:未来科技的基石

目录 什么是云计算? 云计算的分类 1. 基础设施即服务 (IaaS) 2. 平台即服务 (PaaS) 3. 软件即服务 (SaaS) 云计算的优势 1. 成本效益 2. 灵活性和可扩展性 3. 高可用性和可靠性 4. 创新和快速迭代 云计算的应用场景 1. 数据存储和备份 2. 大数据分析 3…

MySQL——基本的Select语句和别名使用

DQL (Data Query Language:数据查询语言) 所有的查询操作都用它 Select 简单或者复杂的查询都能做 数据库中最核心的语言,最重要的语句 使用频率最高的语言 指定查询字段 -- 查询全部的学生 SELECT 字段 FROM 表…

【SpringCloud-Seata客户端源码分析01】

文章目录 启动seata客户端1.导入依赖2.自动装配 发送请求的核心方法客户端开启事务的核心流程服务端分布式事务的处理机制 启动seata客户端 1.导入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent…

【DS Solutions】一个反欺诈产品的进化,Stripe Radar

Stripe Radar 是 Stripe 提供的一项防欺诈服务&#xff0c;它利用机器学习技术来帮助商家检测和阻止信用卡欺诈行为。这篇文章是Stripe公司关于其反欺诈解决方案Stripe Radar的构建过程的介绍。文章从Stripe的防欺诈团队工程师的角度出发&#xff0c;详细讲述了Stripe Radar的工…