GDPU 操作系统 天码行空13

news2024/11/17 3:47:11

文章目录

  • ❌ 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();
        }
    }
}

🏆 运行结果

在这里插入图片描述

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

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

相关文章

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

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

jupyter notebook更改位置

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

Hadoop伪分布式安装教程

Hadoop伪分布式安装教程 一、安装背景1.1 软件列表1.2 系统软件列表 二、安装Hadoop2.1 安装 Java 环境2.1.1 前期准备2.1.2 文件传输2.1.3 解压文件2.1.4 配置 jdk 的环境变量2.1.5 输入 java、javac、java -version 命令检验 jdk 是否安装成功 2.2 Hadoop 下载地址[hadoop](h…

Unix、Linux 软件包管理快速入门对照

Linux&#xff08;RHEL、Ubuntu&#xff09;或者 Unix&#xff08;macOS、FreeBSD&#xff09;可以参看下表快速入门: 命令功能/系统Darwin (macOS)FreeBSDDebian/UbuntuRHEL&#xff08;dnf yum&#xff09;搜索和查找软件包brew searchpkg searchapt listyum list查看软件包…

Compose第一弹 可组合函数+Text

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

基础9 探索图形化编程的奥秘:从物联网到工业自动化

办公室内&#xff0c;明媚的阳光透过窗户洒落&#xff0c;为每张办公桌披上了一层金色的光辉。同事们各自忙碌着&#xff0c;键盘敲击声、文件翻页声和低声讨论交织在一起&#xff0c;营造出一种忙碌而有序的氛围。空气中氤氲着淡淡的咖啡香气和纸张的清新味道&#xff0c;令人…

达梦 结果拼接=多行结果返回一列字符串.

sql 转换 查询出多行数据 (select t.PROPERTY from JD_CODING t left join DELIVERY_OF c on t.VALUE c.TYPE where t.PROPERTY stackingType group by t.PROPERTY) 更改后 转为一列的拼接字符串 ( select listagg( distinct t.PROPERTY,,) within group ( order by t.P…

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 是…

jsRpc js逆向远程调用加密函数

rpc介绍&#xff1a; RPC 全称 Remote Procedure Call——远程过程调用,简单说就是为了解决远程调用服务的一种技术&#xff0c;使得调用者像调用本地服务一样方便透明&#xff1b; 使用RPC服务就可以直接在浏览器中的页面js中注入代码&#xff0c;将其作为一个客户端&#xff…

UML 在 vs-code上的快速使用

UML 在 vs-code上的快速使用 1.软件准备工作2.创建第一张甘特图2.1 创建 UML文件: xxxx. puml2.2 输入甘特图代码2.3 VS code 生成甘特图 结束 。 1.软件准备工作 使用的软件为&#xff1a;VS CODE使用插件 &#xff1a; PluntUML2.创建第一张甘特图 2.1 创建 UML文件: xxxx. …

如何进一步缩短Python性能

1、问题背景 给定一个(x,y)处的节点网格&#xff0c;每个节点有一个值(0…255)从0开始。有N个输入坐标&#xff0c;每个坐标在(0…x, 0…y)的范围内。一个值Z&#xff0c;它定义了节点的“邻域”。增加输入坐标及其邻居节点的值。网格边缘之外的邻居被忽略。基准案例&#xff…

Android下HWC以及drm_hwcomposer普法((上)

Android下HWC以及drm_hwcomposer普法((上) 引言 按摩得全套&#xff0c;错了&#xff0c;做事情得全套&#xff0c;普法分析也是如此。drm_hwcomposer如果对Android图形栈有一定研究的童鞋们应该知道它是Android提供的一个的图形后端合成处理HAL模块的实现。但是在分析这个之前…

图像去雾并与其他非物理模型进行对比

matlab clear clc close all imgimread( scene1.jpg);subplot(221),imshow(uint8(img)), title(原始低照度图像”);img(::,1)255-img(::1); img(::,2)255-img(:2); img(:,:3)255-img(: 3); szsize(img); wsZ(2); hsz(1); %计算RGB取最小值后的图像darkl dark l zeros(h,w); for…

2024-2025年跨境电商展览会计划表:共筑未来跨境行业的繁荣

-----------------------------2024年跨境电商展计划如下---------------------------- 2024年&#xff0c;2025年国内跨境电商行业将迎来一系列重大的展会活动&#xff0c;是企业展示品牌、交流趋势、拓展商机的重要平台。全国各地展会排期信息现已出炉&#xff0c;记得收藏哦…

BGP路由策略实验

一、实验拓扑 二、IP分配(骨干) R1&#xff1a; 0/0/0 15.0.0.1 24 0/0/1 18.0.0.2 24 0/0/2 19.0.0.1 24 R2: 0/0/0 16.0.0.1 24 0/0/1 15.0.0.2 24 R3: 0/0/0 17.0.0.2 24 0/0/1 18.0.0.1 24 R4: 0/0/0 16.0…

【Paddle】稀疏计算的使用指南 稀疏ResNet的学习心得 (2) + Paddle3D应用实例稀疏 ResNet代码解读 (1.6w字超详细)

【Paddle】稀疏计算的使用指南 & 稀疏ResNet的学习心得 Paddle3D应用实例稀疏 ResNet代码解读 写在最前面一、稀疏格式简介1. COO&#xff08;Coordinate Format&#xff09;2. CSR&#xff08;Compressed Sparse Row Format&#xff09; 二、Paddle稀疏张量支持1. 创建 C…

34岁嵌入式开发工程师的出路在哪儿?

作为一个从事智能穿戴行业11年的资深从业者&#xff0c;您积累了丰富的技术和经验&#xff0c;IT行业内有很多发展机会和出路可以选择&#xff0c;以下是一些建议供参考&#xff1a;刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到…

JUC从实战到源码:CompletableFuture详细学习

【JUC】- CompletableFuture详细学习 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xf…

elementUI type=“selection“多选框选中 删除 回显 赋值问题 回显数组改变选中状态未改变

业务需求&#xff1a; 点击查询弹列表框 勾选列表选项保存 可删除可重新查询列表添加 遇到的问题&#xff1a;删除之后查询列表selection回显问题 解决&#xff1a;row-click配合:reserve-selection"true"使用 <el-tableref"refPlanTable":data"…

Java多线程(02)—— 线程等待,线程安全

一、如何终止线程 终止线程就是要让 run 方法尽快执行结束 1. 手动创建标志位 可以通过在代码中手动创建标志位的方式&#xff0c;来作为 run 方法的执行结束条件&#xff1b; public static void main(String[] args) throws InterruptedException {boolean flag true;Thr…