GDPU 操作系统 天码行空13

文章目录

  • ❌ TODO:本文仅供参考,极有可能有误
  • 1.生产者消费者问题(信号量)
    • 💖 ProducerConsumerExample.java
      • 🏆 运行结果
    • 💖 ProducerConsumerSelectiveExample.java
      • 🏆 运行结果
  • 2.实现睡觉的理发师问题
    • 💖 BarberShop.java
      • 🏆 运行结果

❌ TODO:本文仅供参考,极有可能有误

1.生产者消费者问题(信号量)

参考教材中的生产者消费者算法,创建5个进程,其中两个进程为生产者进程,3个进程为消费者进程。一个生产者进程试图不断地在一个缓冲中写入大写字母,另一个生产者进程试图不断地在缓冲中写入小写字母。3个消费者不断地从缓冲中读取一个字符并输出。为了使得程序的输出易于看到结果,仿照的实例程序,分别在生产者和消费者进程的合适的位置加入一些随机睡眠时间。

💖 ProducerConsumerExample.java

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class ProducerConsumerExample {// 定义缓冲区的大小为10private static final int BUFFER_SIZE = 10;// 创建一个阻塞队列,用于存放字符,大小为BUFFER_SIZEprivate static final BlockingQueue<Character> buffer = new ArrayBlockingQueue<>(BUFFER_SIZE);// 定义生产者类,继承自Threadstatic class Producer extends Thread {// 是否生成大写字母private final boolean uppercase;// 随机数生成器private final Random random = new Random();// 构造函数,接收一个布尔值,决定生成大写还是小写字母public Producer(boolean uppercase) {this.uppercase = uppercase;}// 重写run方法,定义生产者的行为@Overridepublic void run() {try {// 循环直到线程被中断while (!Thread.currentThread().isInterrupted()) {// 根据是否生成大写字母,生成随机字符char item = uppercase ? Character.toUpperCase((char) ('A' + random.nextInt(26))) :Character.toLowerCase((char) ('a' + random.nextInt(26)));// 将生成的字符放入缓冲区buffer.put(item);// 打印生产信息System.out.println("Produced " + item + " by " + this.getName());// 随机休眠一段时间Thread.sleep(random.nextInt(1000));}} catch (InterruptedException e) {// 捕获InterruptedException异常,并重新中断当前线程Thread.currentThread().interrupt();}}}// 定义消费者类,继承自Threadstatic class Consumer extends Thread {// 随机数生成器private final Random random = new Random();// 重写run方法,定义消费者的行为@Overridepublic void run() {try {// 循环直到线程被中断while (!Thread.currentThread().isInterrupted()) {// 从缓冲区取出一个字符char item = (char) buffer.take();// 打印消费信息System.out.println("Consumed " + item + " by " + this.getName());// 随机休眠一段时间Thread.sleep(random.nextInt(1000));}} catch (InterruptedException e) {// 捕获InterruptedException异常,并重新中断当前线程Thread.currentThread().interrupt();}}}// 主函数,程序的入口点public static void main(String[] args) {// 创建两个生产者线程,一个生成大写字母,一个生成小写字母Producer producer1 = new Producer(true);Producer producer2 = new Producer(false);// 创建三个消费者线程Consumer consumer1 = new Consumer();Consumer consumer2 = new Consumer();Consumer consumer3 = new Consumer();// 启动所有生产者和消费者线程producer1.start();producer2.start();consumer1.start();consumer2.start();consumer3.start();try {// 等待所有线程完成producer1.join();producer2.join();consumer1.join();consumer2.join();consumer3.join();} catch (InterruptedException e) {// 打印异常信息e.printStackTrace();}}
}

可选的实验:在上面实验的基础上实现部分消费者有选择地消费某些产品。例如一个消费者只消费小写字符,一个消费者只消费大写字母,而另一个消费者则无选择地消费任何产品。消费者要消费的产品没有时,消费者进程被阻塞。注意缓冲的管理。

🏆 运行结果

在这里插入图片描述

💖 ProducerConsumerSelectiveExample.java

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.Random;
import java.util.concurrent.TimeUnit;public class ProducerConsumerSelectiveExample {private static final int BUFFER_SIZE = 10;private static final BlockingQueue<Character> buffer = new ArrayBlockingQueue<>(BUFFER_SIZE);static class Producer extends Thread {private final boolean uppercase;private final Random random = new Random();public Producer(boolean uppercase) {this.uppercase = uppercase;}@Overridepublic void run() {try {while (!Thread.currentThread().isInterrupted()) {char item = uppercase ? Character.toUpperCase((char) ('A' + random.nextInt(26))) :Character.toLowerCase((char) ('a' + random.nextInt(26)));buffer.put(item);System.out.println("Produced " + item + " by " + this.getName());Thread.sleep(random.nextInt(1000));}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}static class Consumer extends Thread {private final boolean onlyUppercase;private final Random random = new Random();public Consumer(boolean onlyUppercase) {this.onlyUppercase = onlyUppercase;}@Overridepublic void run() {try {while (!Thread.currentThread().isInterrupted()) {Character item =  buffer.poll(100, TimeUnit.MILLISECONDS); // 等待最多100毫秒if (item ==null) {// 如果没有找到想要的产品,跳过此次循环continue;}// 根据消费者类型进行选择性消费boolean consume = onlyUppercase ? Character.isUpperCase(item) :!onlyUppercase || Character.isLowerCase(item);if (consume) {buffer.remove(item); // 从队列中移除消费的项System.out.println("Consumed " + item + " by " + this.getName());}// 这里不需要 else 块,因为如果 consume 为 false,item 已经被检查过不是所需类型// 并且已经被忽略,不需要再次检查或睡眠Thread.sleep(random.nextInt(1000));}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}public static void main(String[] args) {Producer producer1 = new Producer(true);Producer producer2 = new Producer(false);Consumer consumerUppercaseOnly = new Consumer(true); // 只消费大写字母Consumer consumerLowercaseOnly = new Consumer(false); // 只消费小写字母Consumer consumerAny = new Consumer(true); // 消费任何产品producer1.start();producer2.start();consumerUppercaseOnly.start();consumerLowercaseOnly.start();consumerAny.start();try {producer1.join();producer2.join();consumerUppercaseOnly.join();consumerLowercaseOnly.join();consumerAny.join();} catch (InterruptedException e) {e.printStackTrace();}}
}

🏆 运行结果

在这里插入图片描述

2.实现睡觉的理发师问题

(同步互斥方式采用信号量或mutex方式均可)
理发师问题的描述:一个理发店接待室有n张椅子,工作室有1张椅子;没有顾客时,理发师睡觉;第一个顾客来到时,必须将理发师唤醒;顾客来时如果还有空座的话,他就坐在一个座位上等待;如果顾客来时没有空座位了,他就离开,不理发了;当理发师处理完所有顾客,而又没有新顾客来时,他又开始睡觉。

💖 BarberShop.java

import java.util.concurrent.Semaphore;
import java.util.Random;public class BarberShop {private final int capacity;private final Semaphore barber = new Semaphore(1);private final Semaphore chair = new Semaphore(0);private final Semaphore[] seats;private final Random random = new Random();public BarberShop(int capacity) {this.capacity = capacity;this.seats = new Semaphore[capacity];for (int i = 0; i < capacity; i++) {this.seats[i] = new Semaphore(1);}}public void barberAction() {try {while (!Thread.currentThread().isInterrupted()) {barber.acquire();chair.acquire(); // 理发师等待顾客坐下System.out.println("理发师醒来开始理发。");// 模拟随机理发时间Thread.sleep(random.nextInt(1000) + 100);System.out.println("理发师完成理发。");barber.release(); // 理发师完成服务,可以服务下一个顾客}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}public void customerAction() {try {while (!Thread.currentThread().isInterrupted()) {boolean foundSeat = false;for (Semaphore seat : seats) {if (seat.tryAcquire()) {foundSeat = true;System.out.println("顾客坐在椅子上等待理发。");chair.release(); // 唤醒理发师// 模拟理发师服务时间Thread.sleep(random.nextInt(1000) + 100);System.out.println("顾客离开理发椅。");seat.release(); // 顾客离开,释放椅子break;}}if (!foundSeat) {System.out.println("没有空椅子,顾客离开。");}// 模拟随机顾客到来时间Thread.sleep(random.nextInt(1000) + 500);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}public static void main(String[] args) {final int CAPACITY = 3; // 假设有3张椅子BarberShop shop = new BarberShop(CAPACITY);Thread barberThread = new Thread(() -> shop.barberAction());barberThread.start();// 创建顾客线程Thread[] customerThreads = new Thread[5];for (int i = 0; i < customerThreads.length; i++) {customerThreads[i] = new Thread(() -> shop.customerAction());customerThreads[i].start();}}
}

🏆 运行结果

在这里插入图片描述

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

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

相关文章

【UnityShader入门精要学习笔记】第十五章 使用噪声

本系列为作者学习UnityShader入门精要而作的笔记&#xff0c;内容将包括&#xff1a; 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更&#xff0c;有始无终 我的GitHub仓库 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 使用噪声上…

【JS基础语法04】运算符分类以及运用

一&#xff1a;赋值运算符 1 类型 赋值运算符包括以下&#xff1a;、、-、*、/ 2 原理 &#xff0c;是将等号右边的数赋值给左边以为例(-、*、/和运算逻辑是相同的) let num 5 num2 等价于 let num 5 numnum2 //num7 二&#xff1a;一元运算符 1怎么判断运算符是几元…

多条文本转二维码怎么做?一键批量建码的使用技巧

怎么快速的制作多条文本信息的二维码&#xff1f;随着二维码的广泛使用&#xff0c;现在很多内容都可以通过生成二维码扫码的方式来获取信息&#xff0c;其他文本二维码就是比较常用的一种类型。那么当需要将多条不同的文本内容每条单独生成二维码时&#xff0c;有什么方法可以…

【Uniapp微信小程序】自定义水印相机、微信小程序地点打卡相机

效果图 template 下方的image图片自行寻找替换! <template><view><camerav-if="!tempImagePath && cameraHeight !== 0":resolution="high":frame-size="large":device-position="device":flash="flas…

2台倍福PLC ADS通信配置

倍福PLC的入门应用介绍请参考下面文章链接: 1、倍福PLC简单入门 从零开始倍福TwinCAT 3 PLC 的一个简单项目-CSDN博客文章浏览阅读34次。这篇文章我们介绍如何开始一个简单的倍福PLC项目。https://rxxw-control.blog.csdn.net/article/details/139124427 1、配置路由 2、…

笔记92:离散LQR控制器详细推导

1&#xff09;离散LQR的推导原理&#xff1a; 拉格朗日乘子法都是在等式约束下用的&#xff1b; 对这个性能函数J运用拉格朗日乘子法后&#xff0c;得到的函数是二次型函数&#xff08;即转化为了最优化控制问题&#xff09;&#xff0c;二次型函数只有一个极值点而且是极小值点…

机器视觉分析在加油站安全中的应用:使用手机检测、打电话行为识别

在加油站等高危场所&#xff0c;禁止使用手机是为了防止潜在的火灾和爆炸风险。手机在使用过程中可能产生电火花&#xff0c;而在加油站这种易燃易爆环境中&#xff0c;任何电火花都可能引发严重的安全事故。因此&#xff0c;加油站禁止使用手机是保障安全生产的重要措施。基于…

FDW(Foreign Data Wrapper)

在上一篇博客里&#xff0c;最末尾提到了 FDW。 FDW 到底是什么呢&#xff1f; 标准 FDW&#xff08;Foreign Data Wrapper&#xff09;遵循了 SQL/MED 标准&#xff0c;标准全称&#xff1a;ISO/IEC 9075-9 Management of External Data (SQL/MED) 2003 年&#xff0c;SQL…

小程序内的分包与数据共享

一:数据共享 小程序内的数据共享和vue当中不一样,vue当中的vue实例可以使得所有的组件都能this.store 但是小程序它只有page对象,和组件实例对象.对于vue而言,vue实例可以使得添加的组件都有. 但是page对象页面对象,不能使得页面内部有.只能使得这个页面内能访问.vue实例,会…

Pooling Sequencing

1、混合(Pooling)样本测序研究 https://www.jianshu.com/p/19ce438ccccf 1.1 混合测序基础 测序成本虽然下降了,但对于植物育种应用研究来说还是很高,动不动就上百群体,小小植物个体价值又低,测完了很可能后面就用不到了。这时,混合样本测序是一种省钱的好办法。 混池…

使用PyAutoGUI识别PNG图像并自动点击按钮

在自动化测试、任务批处理等场景中,我们常常需要控制GUI程序的鼠标键盘操作。PyAutoGUI就是一个非常方便的Python模块,可以帮助我们实现这些操作。今天我们就来看看如何使用PyAutoGUI识别屏幕上的PNG图像,并自动点击图像所在位置。 C:\pythoncode\new\autoguirecongnizepng.py …

超结MOS在全桥电路上的应用-REASUNOS瑞森半导体

一、前言 全桥电路定义 全桥电路是一种常见的电子电路&#xff0c;由四个开关管和一个负载组成&#xff0c;可将直流电转换为交流电。 全桥电路的应用领域 全桥电路广泛应用于电力电子领域&#xff0c;如开关电源、变频器、逆变器、电动汽车、工业自动化等领域 。在电路中&…

Make-An-Audio——用于语音生成的提示增强扩散模型

0.引言 论文提出了一个从文本生成语音的扩散模型 Make-An-Audio。该模型将文本提示作为输入&#xff0c;并据此生成语音。例如&#xff0c;输入 “一只猫在喵喵叫&#xff0c;一个年轻女人的声音”&#xff0c;就会输出猫在喵喵叫&#xff0c;一个女人在说话的音频。这项研究已…

RET-CLIP:眼科疾病诊断大模型

RET-CLIP&#xff1a;眼科疾病诊断大模型 RET-CLIP模型的工作流程和架构图表组成部分工作流程 精细拆解应用RET-CLIP模型进行糖尿病视网膜病变分级 论文&#xff1a;http://arxiv.org/pdf/2405.14137v1 代码&#xff1a;https://github.com/sStonemason/RET-CLIP RET-CLIP 是…

Java手动启动jar包

启动jar包&#xff0c;去到当前jar包路径cmd&#xff0c; windows乱码先执行&#xff1a;chcp 65001 java -Xms512m -Xmx1024m -Dfile.encodingutf-8 -jar -Dspring.cloud.nacos.config.server-addr127.0.0.1:8848 -Dspring.cloud.nacos.discovery.server-addr127.0.0.1:8848 …

基于 DCT 的图像滤波

需求分析 对于图像去噪这一需求&#xff0c;我们可以通过DCT&#xff08;离散余弦变换&#xff09;算法来实现。DCT是一种基于频域的变换技术&#xff0c;可以将图像从空间域转换为频域&#xff0c;然后通过滤波等处理方式进行去噪。 针对这一需求&#xff0c;我们需要进行以下…

mmu之TLB的来源与实现

TLB的由来 遇到的问题 对于两级页表(Page Table)的设计&#xff0c;需要访问两次物理内存才可以得到虚拟地址对应的物理地址(一次访问第一级页表&#xff0c;另一次访问第二级页表)&#xff0c;而物理内存的运行速度相对于处理器本身来说&#xff0c;有几十倍的差距; 因此在处…

湘潭大学软件工程专业oracle-sqlplus安装教程

前言 笔者在网上找了一些教程&#xff0c;但是没有装好&#xff0c;或者不知道啥原因&#xff0c;反正就是登不进去老师要求的系统&#xff0c;连接不上服务器&#xff0c;非常苦恼&#xff0c;请教了一下同学&#xff0c;终于弄好了&#xff0c;本文希望能帮助到和我一样有相…

OpenHarmony面向万物智联的应用框架的思考与探索

应用框架&#xff0c;是操作系统连接开发者生态&#xff0c;实现用户体验的关键基础设施。业务的飞速发展促进了应用框架不断演进和变化。 01►业界应用框架的演进 应用是用户使用操作系统/设备的入口&#xff0c;应用框架则是应用开发和运行的基础设施。以移动端为例&#x…

Red Hat Enterprise Linux (RHEL) 8.10 发布 - 红帽企业 Linux 8 完美终结版

Red Hat Enterprise Linux (RHEL) 8.10 (x86_64, aarch64) - 红帽企业 Linux 红帽企业 Linux 8 完美终结版 请访问原文链接&#xff1a;Red Hat Enterprise Linux (RHEL) 8.10 (x86_64, aarch64) - 红帽企业 Linux&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…