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 {
    // 定义缓冲区的大小为10
    private static final int BUFFER_SIZE = 10;
    // 创建一个阻塞队列,用于存放字符,大小为BUFFER_SIZE
    private static final BlockingQueue<Character> buffer = new ArrayBlockingQueue<>(BUFFER_SIZE);

    // 定义生产者类,继承自Thread
    static class Producer extends Thread {
        // 是否生成大写字母
        private final boolean uppercase;
        // 随机数生成器
        private final Random random = new Random();

        // 构造函数,接收一个布尔值,决定生成大写还是小写字母
        public Producer(boolean uppercase) {
            this.uppercase = uppercase;
        }

        // 重写run方法,定义生产者的行为
        @Override
        public 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();
            }
        }
    }

    // 定义消费者类,继承自Thread
    static class Consumer extends Thread {
        // 随机数生成器
        private final Random random = new Random();

        // 重写run方法,定义消费者的行为
        @Override
        public 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;
        }

        @Override
        public 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;
        }

        @Override
        public 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();
        }
    }
}

🏆 运行结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

凡事有利有弊,如果生了一个自闭症的小孩,请说出有利的部分 :独特、专注力、诚实和直接,记忆力

生育一个自闭症小孩可能带来一些独特的优势和积极的方面&#xff0c;尽管也会面临许多挑战。以下是一些可能的有利方面&#xff1a; 独特的视角&#xff1a;自闭症儿童通常有独特的思维方式和视角&#xff0c;他们可能在某些方面比普通人更敏锐。这种独特性可以带来创新的解决方…

Java设计模式 _行为型模式_备忘录模式

一、备忘录模式 1、备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型模式。通过保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。 2、实现思路 &#xff08;1&#xff09;、定义记录数据的格式规范。 &#xff08;2&#xff09;、编…

多家大模型公司被爆“卖身”,有创业者称接单能力很重要

百模大战下&#xff0c;行业开始“洗牌”。 据外媒《The Information》的报道&#xff0c;随着底层通用大模型格局的基本落成&#xff0c;投资者的热情正在转向支持人形机器人等其他技术。 与此同时&#xff0c;科技巨头和生成式AI的早期赢家也正在加速掀起一场新浪潮&#x…

【信息学奥赛】两个整型变量的值交换

【信息学奥赛】两个整型变量的值交换 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 编写如下一个函数&#xff0c;用于将两个整型变量的值交换 输入&#xff1a; 两个数 输出&#xff1a; 交换后的两个数 样例输入&#xff1a; 3 2样…

【大比武08】利用RAG技术构建档案智能问答系统

关注我们 - 数字罗塞塔计划 - # 大比武2024 本篇是参加“华夏伟业”杯第二届档案信息化公司业务与技术实力大比武&#xff08;简称“大比武 2024”&#xff09;的投稿文章&#xff0c;来自燕山大学档案馆&#xff08;校史馆&#xff09;的实际项目&#xff0c;由河北科怡科技…

Kivy 项目51斩百词 5

MRWord\pages\infopage\info.py def read_random_word(self) def read_random_word(self):"""随机读取一条数据"""sql "SELECT * FROM word WHERE id (SELECT word_id FROM today ORDER BY RANDOM() limit 1)"rows select_data(sq…

AdaBoost 乳腺癌数据挖掘

目录 1.数据集背景 2 集成学习方法 AdaBoost集成过程 3 个体学习器 结果评价 准确率以及混淆矩阵 评估集成学习模型的泛化学习能力 评估集成学习模型的多样性 结论 源码 1.数据集背景 乳腺癌数据集是一个非常经典的二元分类数据集&#xff0c;被广泛应用…

Java线程基础

一、相关概念 1、程序 为完成任务&#xff0c;用某种语言编写的一组指令的集合。 2、进程 进程是指运行中的程序。 进程是程序的依次执行过程&#xff0c;或是正在运行的一个程序&#xff0c;是一个动态过程&#xff1a;有自身产生、存在和消亡的过程。 3、线程 线程是由进程创…

拍视频麦克风什么牌子好?户外无线麦克风哪个牌子好,看本期文章

​无线领夹麦克风&#xff0c;作为现代音频技术的重要代表&#xff0c;已经广泛应用于各种场合。它不仅能提高演讲者的声音质量&#xff0c;还能增加演讲的互动性和生动性。然而&#xff0c;面对市场上众多的无线领夹麦克风产品&#xff0c;如何选择一款适合自己的设备成为了一…

产教协同|暴雨AI算力赋能传媒实践教学

近日&#xff0c;“第七届传媒实践教学创新研讨会暨中国高校影视学会实验教学专业委员会年会”在美丽的山城重庆成功举办。本次大会以“拥抱AI&#xff0c;融合共生”为主题&#xff0c;吸引了来自全国200多所高校、30多家企业以及700多位大视听实践教学产学研用各界专家、学者…

react跨组件通信Context

案例&#xff1a;现在有个父-子-孙组件 需要进行组件通信 import { useState } from "react"; // 创建上下文 const CountContext React.createContext();//子组件 const SonComponent (props) > {return (<div><h2>子组件</h2><Grandson…

便携式应急气象站:应急气象监测装备

TH-BQX5便携式应急气象站&#xff0c;作为现代气象监测的重要装备&#xff0c;以其独特的便携性、高效性和灵活性&#xff0c;在应急气象监测领域发挥着至关重要的作用。这类气象站不仅为灾害预警、环境保护、农业生产等多个领域提供了实时、准确的气象数据&#xff0c;还在突发…

记录一次Redisson使用synchronized和分布式锁不生效的原因

最近在开发的过程中&#xff0c;遇到了一个并发场景&#xff0c;用户进行方案复制的时候&#xff0c;当快速点击两次操作的时候&#xff0c;出现了复制方案重名的情况&#xff0c;实际上是复制方案的方案名称&#xff0c;是由后端根据数据库已有的方案名称和当前要复制的方案名…

Hugging face win使用教程(二)

1. 将环境迁移到win&#xff0c;可以直接下载修改好的cuda环境https://download.csdn.net/download/liangjiubujiu/89368302?spm1001.2014.3001.5503 2. 修改hugging face的缓存路径 3. 重启pycharm 4. 编写测试代码&#xff0c;注意可能由于网络链接问题&#xff0c;需要关…

Parasoft C++Test软件静态分析操作指南_编码规范/标准检查

系列文章目录 Parasoft CTest软件安装指南 Parasoft CTest软件静态分析操作指南_编码规范/标准检查 Parasoft CTest软件静态分析操作指南_软件质量度量 Parasoft CTest软件静态分析_自动提取静态分析数据生成文档 Parasoft CTest软件单元测试_操作指南 Parasoft CTest软件单元…

嵌入式进阶——OLED显示器(SPI)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 SPI协议原理图字库芯片中文显示屏原理API的使用 SPI协议 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种同步串行…

嵌入式要卷成下一个Java了吗?

嵌入式要卷成下一个Java了吗&#xff1f; 根据我十年的嵌入式开发经验&#xff0c;嵌入式开发的工资水平相对 Java 较低。不过&#xff0c;嵌入式开发岗位主要集中在第二产业&#xff0c;尤其是电器、电气、机械汽车、航空航天等行业的“智能制造”领域。这些行业属于重资产行…

JWT身份验证相关安全问题

前言&#xff1a;工作中需要基于框架开发一个贴近实际的应用&#xff0c;找到一款比较合适的cms框架&#xff0c;其中正好用到的就是jwt做身份信息验证&#xff0c;也记录一下学习jwt相关的安全问题过程。 JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行…

线上自由DIY预约小程序源码系统 自由DIY你的界面 带完整的的安装代码包以及搭建教程

系统概述 在当今数字化时代&#xff0c;移动应用成为人们生活和工作中不可或缺的一部分。预约小程序作为一种便捷的工具&#xff0c;为用户提供了高效的预约服务体验。而线上自由 DIY 预约小程序源码系统则为开发者和企业提供了更大的自由度和创造力&#xff0c;让他们能够根据…