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.rhkb.cn/news/335277.html

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

相关文章

将四种算法的预测结果绘制在一张图中

​ 声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 之前的一期推文中&#xff0c;我们推出了…

TREK高压发生器维修高压电源615-3-L-JX 615-3

美国TREK高压电源维修故障分析应注意两点&#xff1a; 故障分析检测和故障硬件更换&#xff0c;由高压电源故障和工作表现初步判断故障的类型和哪些硬件出了问题&#xff0c;初步判断缩小检测范围&#xff0c;通过排除法和更替新配件准确找到故障硬件。维修过程需要对trek电源维…

C语言学习笔记之指针(一)

目录 什么是指针&#xff1f; 指针和指针类型 指针的类型 指针类型的意义 指针-整数 指针的解引用 指针 - 指针 指针的关系运算 野指针 什么是野指针&#xff1f; 野指针的成因 如何规避野指针&#xff1f; 二级指针 什么是指针&#xff1f; 在介绍指针之前&#…

【ai】livekit:Agents 1 : Agents Framework 与 LiveKit 核心 API 原语

agents 官方文档LiveKit Agents LiveKit Agents is an end-to-end framework for building realtime, multimodal AI “agents” that interact with end-users through voice, video, and data channels. This framework allows you to build an agent using Python.是一个端到…

2024年6月1日(星期六)骑行禹都甸

2024年6月1日 (星期六&#xff09;骑行禹都甸&#xff08;韭葱花&#xff09;&#xff0c;早8:30到9:00&#xff0c;昆明氧气厂门口集合&#xff0c;9:30准时出发【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点:昆明氧气厂门口集合 &#xff0c;…

010-Linux磁盘介绍

文章目录 1、名词 2、类型 3、尺寸 4、接口/协议/总线 5、命名 6、分区方式 MBR分区 GPT分区 1、名词 磁盘是计算机主要的存储介质&#xff0c;可以存储大量的二进制数据&#xff0c;并且断电后也能保持数据不丢失。早期计算机使用的磁盘是软磁盘&#xff08;Floppy D…

三方语言中调用, Go Energy GUI编译的dll动态链接库CEF

如何在其它编程语言中调用energy编译的dll动态链接库&#xff0c;以使用CEF 或 LCL库 Energy是Go语言基于LCL CEF开发的跨平台GUI框架, 具有很容易使用CEF 和 LCL控件库 interface 便利 示例链接 正文 为方便起见使用 python 调用 go energy 编译的dll 准备 系统&#x…

C++:vector的模拟实现

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一、vector的模拟实现 1.1 迭代器的获取 1.2 构造函数和赋值重载 1.2.1 无参构造函数 1.2.2 有参构造函数&#xff08;对n个对象的去调用他们的构造&#xff09; 1.2.3 迭代器区…

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

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

亮相CCIG2024,合合信息文档解析技术破解大模型语料“饥荒”难题

近日&#xff0c;2024中国图象图形大会在古都西安盛大开幕。本届大会由中国图象图形学学会主办&#xff0c;空军军医大学、西安交通大学、西北工业大学承办&#xff0c;通过二十多场论坛、百余项成果&#xff0c;集中展示了生成式人工智能、大模型、机器学习、类脑计算等多个图…

Compose第一弹 可组合函数+Text

目标&#xff1a; 1.Compose是什么&#xff1f;有什么特征&#xff1f; 2.Compose的文本控件 一、Compose是什么&#xff1f; Jetpack Compose 是用于构建原生 Android 界面的新工具包。 Compose特征&#xff1a; 1&#xff09;声明式UI&#xff1a;使用声明性的函数构建一…

opencascade 快速显示AIS_ConnectedInteractive源码学习

AIS_ConcentricRelation typedef PrsDim_ConcentricRelation AIS_ConcentricRelation AIS_ConnectedInteractive 简介 创建一个任意位置的另一个交互对象实例作为参考。这允许您使用连接的交互对象&#xff0c;而无需重新计算其表示、选择或图形结构。这些属性是从您的参考对…

蓝桥杯嵌入式国赛笔记(4):多路AD采集

1、前言 蓝桥杯的国赛会遇到多路AD采集的情况&#xff0c;这时候之前的单路采集的方式就不可用了&#xff0c;下面介绍两种多路采集的方式。 以第13届国赛为例 2、方法一&#xff08;配置通道&#xff09; 2.1 使用CubeMx配置 设置IN13与IN17为Single-ended 在Parameter S…

今日好料推荐(大数据湖体系规划)

今日好料推荐&#xff08;大数据湖体系规划&#xff09; 参考资料在文末获取&#xff0c;关注我&#xff0c;获取优质资源。 大数据湖体系规划 一、大数据湖简介 大数据湖&#xff08;Data Lake&#xff09;是一个集中式的存储库&#xff0c;用于存储来自各种来源的结构化和…

蓝桥杯杨辉三角

PREV-282 杨辉三角形【第十二届】【蓝桥杯省赛】【B组】 &#xff08;二分查找 递推&#xff09;&#xff1a; 解析&#xff1a; 1.杨辉三角具有对称性&#xff1a; 2.杨辉三角具有一定规律 通过观察发现&#xff0c;第一次出现的地方一定在左部靠右的位置&#xff0c;所以从…

快速下载极客时间课程

仅供学习&#xff0c;切勿商用 1. 下载 下载geektime-downloader&#xff0c;安装到指定文件夹&#xff0c;注意路径尽量不要出现汉字 不想去github上下载的可以直接下载文章顶部的软件安装包。 2. 执行命令 在安装geektime-downloader目录下&#xff0c;点击鼠标右键&…

Spring和Servlet的整合

Servlet对象是谁创建的&#xff1f; 由服务器端创建的 程序启动调用加载spring配置文件代码 Web应用程序启动也需要加载Spring配置文件 Web开发中有三大组件&#xff1a; 1、servlet 2、filter 3、listener&#xff08;request&#xff0c;session&#xff0c;application&…

在docker中运行SLAM十四讲程序

《十四讲》的示例程序依赖比较多&#xff0c;而且系统有点旧。可以在容器中运行。 拉取镜像 docker pull ddhogan/slambook:v0.1这个docker对应的github&#xff1a;HomeLH/slambook2-docker 拉下来之后&#xff0c;假如是Windows系统&#xff0c;需要使用XLaunch用于提供X11…

无人机操作界面来了,起点就很高呀。

无人机操作界面设计需要考虑以下几个方面&#xff1a; 易用性&#xff1a;无人机操作界面应该简单直观&#xff0c;易于操作和理解。操作按钮和控键应该布局合理&#xff0c;易于触摸或点击。重要的操作功能应该易于找到和使用&#xff0c;避免用户迷失或困惑。实时反馈&#…

jupyter notebook更改位置

1.找到jupyer的配置文件 一般在c盘用户的.jupter文件夹下 2. 用记事本打开这个配置文件&#xff0c;定位到c.NotebookApp.notebook_dir /path_to_your_directory 替换你的位置 3.找到jupyer图标的位置&#xff0c;打开属性 添加要存放的位置在目标文件的末尾&#xff0c;重新…