Java 生产者和消费者模式练习 (2024.8.12)

embedded/2024/9/25 3:23:23/

        ProducerAndConsumerExercise1

java">package ProducerAndConsumer20240812;public class ProducerAndConsumerExercise1 {public static void main(String[] args) {// 生产者(Producer)和消费者(Consumer)模式// 这是一个十分经典的多线程协作模式,其主要包含了两类线程// 1.生产者线程:用于生产数据(提供给消费者数据)// 2.消费者线程:用于消费数据(使用生产者的数据)// 实现生产者和消费者的关系,通常采用共享的数据区域;生产者将数据直接放置于共享数据区中,无需关心消费者的行为//                                              而消费者若需要则直接去共享数据区获取数据,无需关系生产者的行为// Object类中的等待和唤醒方法// void wait() 使当前线程进入等待,知道另一个线程调用该对象的notify()方法或notifyAll()方法// void notify() 唤醒正在等待对象监视器的单个线程// void notifyAll() 唤醒正在等待对象监视器的全部线程}
}

        ProducerAndConsumerExercise2

java">package ProducerAndConsumer20240812;public class ProducerAndConsumerExercise2 {public static void main(String[] args) {/* 案例需求:桌子类(Desk):定义表示汉堡包数量的变量,定义锁对象变量,定义标记桌子上有无汉堡包的变量生产者类(Cooker):实现Runnable接口,重写run()方法,设置线程任务:1.判断是否有汉堡包,决定当前线程是否执行2.如果有汉堡包,就进入等待状态,如果没有汉堡包,继续执行,生产汉堡包3.生产汉堡包之后,更新桌子上汉堡包状态,唤醒消费者消费汉堡包消费者类(Foodie):实现Runnable接口,重写run()方法,设置线程任务:1.判断是否有汉堡包,决定当前线程是否执行2.如果没有汉堡包,就进入等待状态,如果有汉堡包,就消费汉堡包3.消费汉堡包后,更新桌子上汉堡包状态,唤醒生产者生产汉堡包测试类(Demo):里面有main方法,main方法中的代码步骤如下:创建生产者线程和消费者线程对象分别开启两个线程*/Cook cook = new Cook();Foodie foodie = new Foodie();Thread thread1 = new Thread(cook, "厨师");Thread thread2 = new Thread(foodie, "顾客");thread1.start();thread2.start();}
}

        Cook

java">package ProducerAndConsumer20240812;public class Cook implements Runnable{@Overridepublic void run() {while (true) {synchronized (Desk.lock) {if (Desk.makeCount == 10) {break;} else {if (Desk.flag) {// 此时表示有汉堡try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {// 此时表示没有汉堡包了Desk.makeCount++;System.out.println(Thread.currentThread().getName() +  "正在生产第" + Desk.makeCount +"汉堡包");Desk.count++;System.out.println("桌子上现在有" + Desk.count + "个汉堡包");if (Desk.count > 0) {Desk.flag = true;}Desk.lock.notifyAll();}}}}}
}

        Foodie

java">package ProducerAndConsumer20240812;public class Foodie implements Runnable {@Overridepublic void run() {while (true) {synchronized (Desk.lock) {if (Desk.eatCount == 10) {break;} else {if (Desk.flag) {// 此时是有汉堡的,顾客可以开始吃Desk.eatCount++;System.out.println(Thread.currentThread().getName() +  "正在吃第" + Desk.eatCount +"汉堡包");Desk.count--;System.out.println("桌子上现在有" + Desk.count + "个汉堡包");if (Desk.count == 0) {Desk.flag = false;}Desk.lock.notifyAll();} else {// 此时是没有汉堡的,顾客进入等待try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
}

        Desk

java">package ProducerAndConsumer20240812;public class Desk {public static int eatCount = 0;public static int makeCount = 0;public static int count = 0;public static final Object lock = new Object();public static boolean flag = false;
}

         ProducerAndConsumerExercise3

java">package ProducerAndConsumer20240812;public class ProducerAndConsumerExercise3 {public static void main(String[] args) {// 需求:/* 将Desk类中的变量,采用面向对象的方式封装起来生产者和消费者类中构造方法接收Desk类对象,之后在run方法中进行使用创建生产者和消费者线程对象,构造方法中传入Desk类对象开启两个线程*/DeskPro deskPro = new DeskPro();CookPro cookPro = new CookPro(deskPro);FoodiePro foodiePro = new FoodiePro(deskPro);Thread thread1 = new Thread(cookPro, "厨师");Thread thread2 = new Thread(foodiePro, "顾客");thread1.start();thread2.start();}
}

        CookPro

java">package ProducerAndConsumer20240812;public class CookPro implements Runnable {private DeskPro desk;public CookPro(DeskPro desk) {this.desk = desk;}@Overridepublic void run() {while (true) {synchronized (desk.getLock()) {if (desk.getMakeCount() == 10) {break;} else {if (desk.isFlag()) {// 此时桌子上面有汉堡包,厨师等待try {desk.getLock().wait();} catch (InterruptedException e){e.printStackTrace();}} else {// 此时桌子上面没有汉堡包,厨师开始做汉堡int makeCount = desk.getMakeCount();desk.setMakeCount(++makeCount);System.out.println(Thread.currentThread().getName() + "正在做第" + desk.getMakeCount() + "个汉堡包");int count = desk.getCount();desk.setCount(++count);if (desk.getCount() > 0) {desk.setFlag(true);}// 叫醒顾客来吃汉堡desk.getLock().notifyAll();}}}}}
}

        FoodiePro

java">package ProducerAndConsumer20240812;public class FoodiePro implements Runnable {private DeskPro desk;public FoodiePro (DeskPro desk) {this.desk = desk;}@Overridepublic void run() {while (true) {synchronized (desk.getLock()) {if (desk.getEatCount() == 10) {// 吃了10个吃饱了break;} else {if (desk.isFlag()) {// 此时桌子上有汉堡,顾客开始吃汉堡int eatCount = desk.getEatCount();desk.setEatCount(++eatCount);System.out.println(Thread.currentThread().getName() + "正在吃第" + desk.getEatCount() + "个汉堡");int count = desk.getCount();desk.setCount(--count);if (desk.getCount() == 0) {desk.setFlag(false);}// 叫醒厨师来做汉堡desk.getLock().notifyAll();} else {// 此时桌子上没有汉堡,顾客等待厨师做汉堡try {desk.getLock().wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
}

        DeskPro

java">package ProducerAndConsumer20240812;public class DeskPro {private boolean flag;private int makeCount;private int eatCount;private int count;private final Object lock = new Object();public DeskPro() {this(false, 0, 0, 0);}public DeskPro(boolean flag, int makeCount, int eatCount, int count) {this.flag = flag;this.makeCount = makeCount;this.eatCount = eatCount;this.count = count;}public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public int getMakeCount() {return makeCount;}public void setMakeCount(int makeCount) {this.makeCount = makeCount;}public int getEatCount() {return eatCount;}public void setEatCount(int eatCount) {this.eatCount = eatCount;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public Object getLock() {return lock;}
}

 

 

 

 

 

 

 


http://www.ppmy.cn/embedded/94296.html

相关文章

「阅读」数据密集型系统设计 第四章 编码

第四章 编码和演化 一、为什么需要考虑编码? 在大型应用程序中,代码变更无法立刻生效。原因如下: 服务端程序:代码往往通过灰度发布方式,新版本主键部署到所有节点客户端程序:取决于用户是否更新 上述过…

[论文翻译] LTAChecker:利用注意力时态网络基于 Dalvik 操作码序列的轻量级安卓恶意软件检测

LTAChecker: Lightweight Android Malware Detection Based on Dalvik Opcode Sequences using Attention Temporal Networks 摘要: Android 应用程序已成为黑客攻击的主要目标。安卓恶意软件检测是一项关键技术,对保障网络安全和阻止异常情况至关重要。…

基于大数据的气象数据分析与可视化系统设计与实现【爬虫海量数据,LSTM预测】

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍研究目的研究意义研究思路可视化展示每文一语 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍 本课题主要针对气象数据进行分析以及可视化…

在一串字符串中Java使用正则匹配电话号码的方法

1.使用正则表达式来匹配电话号码 在Java中,使用正则表达式匹配电话号码是一个常见的需求。电话号码的格式可能因国家/地区而异,但一个典型的格式可能是这样的:(123) 456-7890。在这个例子中,我将提供一个Java程序,该程…

立体相机镜面重建(二)双目立体镜面重建

使用双目相机,配合镜子、屏幕,可以直接获得镜面的三维数据,无需先验知识。因此使用双目镜面重建方式对镜子表面进行重建。 (一)重建步骤 使用左相机光线法来计算镜面点: 1.取一个像素点,计算其…

【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】017 - init_sequence_f 各函数源码分析(一)

【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】017 - init_sequence_f 各函数源码分析(一) 一、setup_mon_len():配置 gd->mon_len 监控长度二、fdtdec_setup() :设备树初始化,配置 gd->fdt_blob 指向uboot镜像末尾的 device tree三、【RK3568未跑】trace_early…

Python 在开发中的设计模式有哪些?怎样使用?

大家好!我是爱摸鱼的小鸿,关注我,收看每期的编程干货。 今天我们要聊点硬核的——设计模式。不过,不用担心,我会带着热情来跟你分享这些看似枯燥的知识点。让我们一起从“代码搬砖工”蜕变成“代码艺术家”吧&#xff…

常见8种数据结构

常见的数据结构包括数组、链表、队列、栈、树、堆、哈希表和图,每种数据结构都有其特点,如下: 常见数据结构 1.数组2.链表3.队列4.栈5.树6.图7.哈希表8.堆 1.数组 特点: 固定大小的线性数据结构支持快速随机访问插入和删除效率…