算法:哲学家就餐问题

news2024/11/15 14:06:31

问题描述

由Dijkstra提出并解决的哲学家就餐问题是典型的同步问题。该问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替的进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。

图:

alt

解答思路

面向对象编程

  1. 要定义哲学家对象,Philosopher,哲学家对象里面要有编号,要有左右的筷子
  2. 定义筷子对象 ChopStick

正常定义的情况下肯定是会出现死锁的场景。因为每个人都依赖他下面一个筷子才能吃饭 解决方法就是,让最后一个人先拿右边筷子,再拿左边筷子,这样就会有一个人会先拿到右手,又回拿到左手的情况。就会先吃完饭,释放锁

解题:有一个人先右手,就不会产生死锁

0号哲学家 先拿了 0 号筷子 4号哲学家 拿了 4 号筷子 3号哲学家 拿了 3号筷子 2号哲学家 拿了 2号筷子 1号哲学家 先去拿 0号筷子,发现0号筷子已经被拿了,就等到。这个时候 2号哲学家就能同时拿到 2号筷子和1号筷子。就吃完饭释放锁了。

同理 3号吃完 4号吃完 0号吃完 1号吃完

场景死锁锁的情况 编码

package com.leeue.demo;

/**
 * 哲学家吃饭问题,死锁案例
 *
 * @Author liyue
 * @date 2023/7/1 10:44
 **/

/**
 * 哲学家实体类
 */
class Philosopher extends Thread {
    int index;
    ChopStick left;
    ChopStick right;

    public Philosopher(int index, ChopStick left, ChopStick right) {
        this.index = index;
        this.left = left;
        this.right = right;
    }

    @Override
    public void run() {
        synchronized (this.left) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (this.right) {
                System.out.println("哲学家:" + index + "吃上饭了");
            }
        }
    }
}

/**
 * 筷子实体类
 */
class ChopStick {

}


public class PhilosopherDeadLock {

    public static void main(String[] args) {
        ChopStick chopStick_0 = new ChopStick();
        ChopStick chopStick_1 = new ChopStick();
        ChopStick chopStick_2 = new ChopStick();
        ChopStick chopStick_3 = new ChopStick();
        ChopStick chopStick_4 = new ChopStick();

        Philosopher philosopher_0 = new Philosopher(0, chopStick_0, chopStick_4);
        Philosopher philosopher_1 = new Philosopher(1, chopStick_1, chopStick_0);
        Philosopher philosopher_2 = new Philosopher(2, chopStick_2, chopStick_1);
        Philosopher philosopher_3 = new Philosopher(3, chopStick_3, chopStick_2);
        Philosopher philosopher_4 = new Philosopher(4, chopStick_4, chopStick_3);

        philosopher_0.start();
        philosopher_1.start();
        philosopher_2.start();
        philosopher_3.start();
        philosopher_4.start();
    }
}

死锁解决代码

package com.leeue.demo;

/**
 * 哲学家吃饭问题,死锁案例
 *
 * @Author liyue
 * @date 2023/7/1 10:44
 **/

/**
 * 哲学家实体类
 */
class Philosopher extends Thread {
    int index;
    ChopStick left;
    ChopStick right;

    public Philosopher(int index, ChopStick left, ChopStick right) {
        this.index = index;
        this.left = left;
        this.right = right;
    }

    @Override
    public void run() {

        if (index == 0) {
            synchronized (this.right) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (this.left) {
                    System.out.println("哲学家:" + index + "吃上饭了");
                }
            }
        } else {
            synchronized (this.left) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (this.right) {
                    System.out.println("哲学家:" + index + "吃上饭了");
                }
            }
        }


    }
}

/**
 * 筷子实体类
 */
class ChopStick {

}


public class PhilosopherDeadLockOpen {

    public static void main(String[] args) {
        ChopStick chopStick_0 = new ChopStick();
        ChopStick chopStick_1 = new ChopStick();
        ChopStick chopStick_2 = new ChopStick();
        ChopStick chopStick_3 = new ChopStick();
        ChopStick chopStick_4 = new ChopStick();

        Philosopher philosopher_0 = new Philosopher(0, chopStick_0, chopStick_4);
        Philosopher philosopher_1 = new Philosopher(1, chopStick_1, chopStick_0);
        Philosopher philosopher_2 = new Philosopher(2, chopStick_2, chopStick_1);
        Philosopher philosopher_3 = new Philosopher(3, chopStick_3, chopStick_2);
        Philosopher philosopher_4 = new Philosopher(4, chopStick_4, chopStick_3);

        philosopher_0.start();
        philosopher_1.start();
        philosopher_2.start();
        philosopher_3.start();
        philosopher_4.start();
    }
}

思考 1万个哲学家该如何提交效率进行吃饭。

可以多定义几个哲学家先拿右手再拿左手的逻辑。如:%2 == 0 的可以走先拿右手再拿左手的逻辑

本文由 mdnice 多平台发布

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

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

相关文章

大语言模型微调和PEFT高效微调

目录标题 1 解释说明1.1 预训练阶段1.2 微调阶段2 几种微调算法2.1 在线微调2.2 高效微调2.2.1 RLHF2.2.2 LoRA2.2.3 Prefix Tuning2.2.4 Prompt Tuning2.2.5 P-Tuning v21 解释说明 预训练语言模型的成功,证明了我们可以从海量的无标注文本中学到潜在的语义信息,而无需为每一…

信号链噪声分析11

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示:这里可以添加技术概要 如今的射频(RF)系统变得越来越复杂。高度的复杂性要求所有系统指标(例如严格的 链接和噪声预算)达到最佳性能。确保整个信号链的正确设计至关重要。而信…

深入乳腺癌谜团:无监督学习与R语言的勘探之旅

一、引言 乳腺癌作为全球常见的恶性肿瘤,给患者和医学界带来了巨大的挑战。据世界卫生组织的数据显示,乳腺癌是妇女中最常见的癌症之一,并且是全球癌症相关死亡的主要原因之一[1]。因此,研究乳腺癌,并努力提高其早期检…

1085会议桌牌

机种名 蓝牙会议桌牌 型号 PE1085R_D_BLE 外观尺寸 280x58x129.9mm 可视区域 258.7690.68mm 外观颜色 银色 工作电源 3.7V锂电池供电,Type C充电口 显示技术 E-INK电子纸,双屏 像素 1360x480 像素颜色 黑/白/红 视角 约180 适用温度 …

【Java】直接return 会触发try-catch 里面的finally的方法么

🐱‍🚀/背景 try-catch 主要的作用是捕获异常,那么程序没有异常,finally里面代码能否执行? 特别是如果我们前面进行了加锁等操作,没有释放锁,那不是会造成业务逻辑问题, 先说结论:…

Eclipse成立新工作组,华为和谷歌等是初始成员

日前一个供应商中立,并由社区支持的Visual Studio第三方开源市场Open VSX Registry迎来新工作组的成立。根据了解,开发者可以在Open VSX Registry当中的市场中自由上架、下载安装Visual Studio的各种第三方扩展。 随即Eclipse基金会宣告成立了Open VSX工…

前缀迷宫:解密力扣统计包含给定前缀的字符串

本篇博客会讲解力扣“2185. 统计包含给定前缀的字符串”的解题思路,这是题目链接。 本题的思路是:遍历字符串数组,判断遍历到的字符串是否包含给定前缀。 判断的方法是:使用strncmp函数,比较该字符串的前strlen(pref)…

【Linux】工具介绍——vim及gcc

前言 在Linux操作系统之中有很多使用的工具,我们可以用vim来进行程序的编写,然后用gcc来生成可执行文件,最终运行程序。本文来带大家了解vim和gcc,以及自动化构建工具Makefile,这三个工具的使用方法。 一、vim 1.vi…

Webpack打包arcgis js api 3.x纯html+JS+CSS项目

需求 小项目。纯HTMLJSCSS已经部署上线,但是没有做混淆加密,需要进行混淆加密 分析 目前代码里面需要混淆加密的有main.js,其他的不用混淆加密。所以只需要对main.js进行混淆加密就可,但是要保证混淆加密之后能够访问方法。由于…

C#中的自定义组件(单一组件和复杂组件)

简单的应用程序开发可能不必要制作组件,C#中丰富的组件足以应对绝大多数的开发设想。 稍微复杂一些的应用开发,或者平台开发,或者团队开发,不可避免地要涉及到基础库的搭建,其中会有很多用户组件的设计与开发。 组件分…

计算机视觉 - 理论 - 从卷积到识别

计算机视觉 - 理论入门 前言一,导论:二,卷积:图像去噪:常值卷积:高斯卷积:椒盐去噪:锐化程度: 三,边缘检测:图像信号导数:求导算子:图…

计算机网络-网络层上篇

目录 一、网络层概述 二、网络层提供的两种服务 (一)面向连接的虚电路服务 (二)无连接的数据报服务 (三)虚电路服务与数据报服务的比较 三、IPv4地址及其应用 (一)IPv4地址概…

【AI底层逻辑】——篇章4:大数据处理与挖掘

目录 引入 一、大数据概述 二、数据处理的流程&方法 1、数据收集——“从无到有” 2、数据加工——“从有到能用” 3、数据分析 三、大数据改变了什么 往期精彩: 引入 AI的表现依赖大数据。曾经一段时间,对于图像识别的准确率只能达到60%~70…

BUUCTF 还原大师 1

题目描述: 我们得到了一串神秘字符串:TASC?O3RJMV?WDJKX?ZM,问号部分是未知大写字母,为了确定这个神秘字符串,我们通过了其他途径获得了这个字串的32位MD5码。但是我们获得它的32位MD5码也是残缺不全,E903???4D…

Elasticsearch 集群日志收集搭建

Elasticsearch-7.2.0Logstash-7.2.0Kibana-7.2.0-Filebeat-7.6.0 第一台集群内网ip:10.0.0.223 ES配置文件:/es_data/es/elasticsearch-7.2.0/config/elasticsearch.yml ES启动命令:/es_data/es/elasticsearch-7.2.0/bin/elasticsearch cl…

报道|本科专业对收入影响巨大!最高以及最低收入的专业有这些

作者:Aimee Picchi 编者按 本文引用并翻译了发表在美国CBS的最新研究,希望能给刚高考完正在挑选大学以及专业的准大学生们一点帮助哦。 最新的研究发现,一个学生的专业和母校能明显地影响ta毕业四年后的收入水平。HEA Group的调查显示&#x…

Jenkins + gitlab 自动部署

1. 背景 作为后台开发,每次我们开发完或者修改一个bug后都要手动合并,打包或者连接服务器执行打包部署命令,每次手动操作,极大的影响了我们的开发效率,那么有没有一款工具能让我们只需要推送/合并代码到远端就能实现服…

【小沐学Python】Python实现Web服务器(Flask框架扩展:Flask-SQLAlchemy)

文章目录 1、简介2、安装3、开发3.1 数据库连接字符串3.2 SQLAlchemy参数设置3.3 SQLAlchemy字段类型3.4 SQLAlchemy列选项3.5 SQLAlchemy关系选项3.6 SQLAlchemy操作接口 4、代码测试4.1 用户管理4.2 用户角色管理4.3 学生管理4.4 图书管理 结语 1、简介 SQLAlchemy SQLALche…

windows下安装Visual Studio + CMake+OpenCV + OpenCV contrib+TensorRT

目录 1 安装visual studio 2 安装CMake 3 OpenCV源码安装 3.1 OpenCV源码下载 3.2 OpenCV contrib源码下载 3.3 安装OpenCV 3.4 安装OpenCV-crontrib 3.5 VS生成代码 4 环境配置 5 TensorRT安装 5.1 TensorRT安装 5.2 Python下安装TensorRT库 最近在研究windows系统…

Android学习_Mars老师之Mp3视频开发

实现的功能&#xff1a;开发一个可以播放音乐并同步显示歌词文件的APP. 成果展示&#xff1a; 总体设计图&#xff1a; 实现流程图 代码展示&#xff1a; AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:androi…