Java实现哲学家就餐问题

Java基础学习之并发篇:哲学家就餐问题 学习目标 提示:这里可以添加学习目标 例如:一周掌握 Java 入门知识 阅读详情

什么是哲学家就餐问题?

我给出一种方法的实现

Chandy/Misra解法

1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解法,允许任意的用户(编号P1, …,
Pn)争用任意数量的资源。与资源分级解法不同的是,这里编号可以是任意的。

  • 把筷子凑成对,让要吃的人先吃,没筷子的人得到一张换筷子券。
  • 饿了,把换筷子券交给有筷子的人,有筷子的人吃饱了会把筷子交给给券的人。有了券的人不会再得到第二张券。 保证有筷子的都有得吃。
  • 这个解法允许很大的并行性,适用于任意大的问题。

Java代码

  • Util.java
package com.coderbean.test;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Chang on 15/11/19.
 */
public class Util {
    int num = 0;
    List<Philosopher> philosopherList;  //store philosophers

    public Util() {
        philosopherList = new ArrayList<>();
//        philosopherList = new ArrayList<Philosopher>();
    }

    public Util(int num) {
        this();
        this.num = num;
    }

    public synchronized boolean getForks() {
        if(num>2) {
            num -= 2;
            return true;
        } else {
            return false;
        }
    }

    public synchronized void findBoss(Philosopher phi) {
        for(Philosopher p:philosopherList) {
            if(phi==p)
                continue;
            if(p.hasForks()&&!p.hasTicket()) {
                p.setPhilosopher(phi);
                p.setHasTicket(true);
                System.out.println(phi.getName()+"'s Boss is " +p.getName());
                phi.setHasTicket(false);
                System.out.println(""+phi.hasForks()+"餐具-"+phi.getName());
                phi.setHasForks(false);
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized void freeForks(Philosopher philosopher) {
        philosopher.getPhilosopher().setHasForks(true);
        System.out.println(""+philosopher.getName()+"给了"+philosopher.getPhilosopher().getName()+"餐具");
        philosopher.setHasForks(false);
        notifyAll();
    }
    public synchronized void debug() {
        System.out.println("\n" + philosopherList.size());
        for (Philosopher p : philosopherList) {
            System.out.println(p.hasForks() + "-" + p.hasTicket() + "\n");
        }
    }
}
  • Philosopher.java
package com.coderbean.test;

/**
 * Created by Chang on 15/11/19.
 */
public class Philosopher implements Runnable {
    private Util util;
    private String name;
    private boolean hasTicket;
    private boolean hasForks;
    private Philosopher philosopher;


    public Philosopher() {
        name = null;
        util = new Util();
        hasTicket = false;
        hasForks = false;
    }

    public Philosopher getPhilosopher() {
        return philosopher;
    }

    public String getName() {
        return name;
    }

    public void setPhilosopher(Philosopher philosopher) {
        this.philosopher = philosopher;
    }

    public boolean hasTicket() {
        return hasTicket;
    }

    public void setHasForks(boolean hasForks) {
        this.hasForks = hasForks;
    }

    public boolean hasForks() {
        return hasForks;
    }

    public void setHasTicket(boolean hasTicket) {
        this.hasTicket = hasTicket;
    }

    /**
     * 构造方法
     * @param util 筷子管理程序
     * @param name 哲学家名字
     */
    public Philosopher(Util util, String name) {
        this();
        this.util = util;
        this.name = name;
    }



    public void think(){
        System.out.println("I am Thinking----"+this.name);
        try {
            Thread.sleep(1000);  //模拟思考耗时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void eat() {
        System.out.println("----------------------------I am Eating--"+this.name);
        try {
            Thread.sleep(500); //模拟吃饭耗时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void run() {
        philosopher = new Philosopher();
        this.util.philosopherList.add(this); //take self to the list in Util
        this.hasForks = util.getForks();
        this.hasTicket = !this.hasForks;

        while (true) {
            this.think();

            if (this.hasForks) { // if has forks ,eat
                eat();
                if (this.hasTicket) { //有票有筷子 if has ticket, give forks to the ticket owner
                    util.freeForks(this);
                }//有筷子没票 什么都不干

            } else if (this.hasTicket) { //有票没筷子,找有筷子的人,给他票
                util.findBoss(this);
            }// 没筷子没票,什么都不敢
//            util.debug();
        }
    }
}
  • Main.java
package com.coderbean.test;

/**
 * Created by Chang on 15/11/19.
 */
public class Main {
    public static void main(String[] args) {
        Util util = new Util(5);
        new Thread(new Philosopher(util,"1")).start();
        new Thread(new Philosopher(util,"2")).start();
        new Thread(new Philosopher(util,"3")).start();
        new Thread(new Philosopher(util,"4")).start();
        new Thread(new Philosopher(util,"5")).start();
    }
}
哲学家就餐问题的解决(java实现) 前言: 生产者-消费者模型和哲学家就餐问题是多线程中比较经典的两个问题.通过这两个问题,可以很好地了解和实践下java多线程的基础知识. 哲学家就餐问题: 有五个哲学家,他们的生活方式是交替地进行思考和进餐。他们共用一张圆桌,分别坐在五张椅子上。 在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐完毕,放下筷子又继续思考。 对java多线程不熟悉的可以先看下生产者-消费者模型是怎么实现的,然后再独立实现哲学. 阅读详情

相关推荐

JAVA实现哲学家就餐问题

用JAVA实现哲学家就餐问题,本源码中采用的是奇数号哲学家先拿左手后拿右手,而偶数号哲学家采用先拿右手后拿左手的策略来预防死锁。

哲学家就餐问题(java实现)

史上最全哲学家就餐问题解法

cchoop的博客 1904

【智能教育实践】MOOPer数据集在个性化学习路径规划中的应用

本文探讨了如何利用MOOPer数据集实现从“千人一面”到“千人千面”的个性化学习路径规划。通过分析学习者与平台的交互数据(如练习、反馈、讨论)并结合知识图谱,系统能够动态诊断学生知识状态,并为其推荐最优学习序列。文章详细介绍了基于数据驱动的推荐系统核心技术,包括知识追踪、图谱关联挖掘及排序策略,旨在解决传统在线教育的僵化问题,提升学习效率与动力。

read5的博客 230

哲学家就餐问题(java全代码)

java实现哲学家就餐问题

weixin_60401853的博客 1297

如何在高版本的ubuntu系统里安装gcc4.1.2

1、下载安装包,一共五个http://archive.ubuntu.com/ubuntu/pool/universe/g/gcc-4.1/,根据计算机系统位数   进行下载,64位下载amd64结尾的。开头分别是cpp-4.1_4.1.2、g++-4.1_4.1.2、gcc-4.1-base_4.1.2、gcc-     4.1_4.1.2、libstdc++6-4.1 2、使用sudo d

lsr_fighting的博客 1931

SAM3模型国内快速上手:Modelscope权重下载+环境配置一条龙指南

本文详细介绍了SAM3模型在国内的快速部署方案,包括通过Modelscope平台下载权重文件、优化CUDA 11.8环境配置以及实战避坑技巧。针对国内开发者常见的网络问题和环境兼容性问题,提供了从权重下载到模型加载的全流程指南,帮助用户高效完成部署并快速上手SAM3模型。

weixin_28465009的博客 1139

哲学家就餐:死锁及解决方案 Java

如果 4 个哲学家同时拿起左边编号较小的餐叉,第 5 个哲学家左边是优先级 4,右边是优先级 0,因为 0 已经被占用了,所以他无法拿起餐叉,因此不会发生死锁。假如当前有 0~4 五个哲学家,0,2 正在吃饭,这时 1 由于两个餐叉都被占用而无法吃饭,对于 3,如果这时拿起剩余的一只餐叉,就有可能发生死锁。每个哲学家不能公平地获取到餐叉,如果哲学家 1 拿餐叉的速度很慢,哲学家 2 思考速度很快,每次都会很快把餐叉拿起来,那么哲学家 1 永远不能拿起右手边的餐叉。如果是脏的,则擦干净并交出餐叉。

腐烂的橘子 1282

潜流式人工湿地计算_复合人工湿地净化水产养殖污水技术

技术概论1. 定义与分类人工湿地是指用人工筑成水池或沟槽,底面铺设防渗漏隔水层,充填一定深度的基质层,种植水生植物,利用基质、植物、微生物的物理、化学、生物三重协同作用使污水得到净化的系统。当池塘养殖污水进入人工湿地时,其污染物被床体吸附、过滤、分解而达到水质净化作用。按照水体流动方式,人工湿地分为表面流人工湿地、水平潜流人工湿地、垂直潜流人工湿地以及由前面几种湿地混合搭配的组合式人工湿...

weixin_42365490的博客 4244

Java并发-哲学家吃饭问题

科学家吃饭问题

abc123mma的博客 687

服务器测试之网卡性能调优

nvidia下载mlnx_ofed:https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/intel下载驱动固件:https://www.intel.com/content/www/us/en/download-center/home.html。然而,你可以根据实际情况手动调整中断相关配置。老生常谈了,一些性能相关的设置项打开,节能的关闭,虚拟化相关的VMX/SR-IOV/IOMMU最好也都关掉。

qq_41897488的博客 4907

使用DrissionPage实现携程酒店信息智能爬取

本文介绍了一个基于DrissionPage技术的携程酒店信息爬虫系统,通过监听API数据包实现高效采集。系统可自动获取酒店名称、价格、评分、位置等15个维度的数据,支持多页滚动加载和智能去重。相比传统爬虫,该方法直接解析API返回的JSON数据,避免了复杂的HTML解析和加密参数分析,提高了开发效率和稳定性。文章详细阐述了13个关键实现步骤,并强调数据采集应严格遵守法律法规,仅用于技术学习和市场研究。该系统可为旅游决策、价格监测等提供数据支持,但需注意合理使用频率和隐私保护。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 386

用 Java 实现 哲学家就餐问题

这篇文章分析了死锁产生的条件,并使用 Java 实现经典的哲学家就餐问题以复现死锁,并给出解开死锁的解决方案。

lybugproducer的博客 693

LIN协议V2.2A版介绍

IN 协议规范2.2A 版(2010 年 12 月发布)是面向低成本汽车网络的标准,核心采用单主多从架构,支持最高20kbit/s速率,通过单总线实现通信;定义了完整的协议栈(含协议层、传输层、物理层等),规定了帧结构(含 Break 字段、Sync 字节、保护标识符 PID、数据字段、校验和)、5 类帧类型(无条件帧、事件触发帧等)及调度表机制以保障确定性传输;

qflook的博客 319

哲学家就餐问题及其一种java多线程实现

哲学家就餐问题,是并行程序中的一个经典问题,qi mian s

softee的专栏 1851

黑猫带你学UFS协议第8篇:UFS电气特性详解(Power、CLK、Reset等)

UFS强制支持secure mode。UFS设备可能会存储个人或者公司的信息,UFS提供把数据永久从设备上移除的功能,并且保证对存储介质进行逆向恢复数据也恢复不回来原有数据。安全模式是以逻辑单元为单位进行应用的,不同的逻辑单元可以有不同的安全模式。由于UFS设备的存储介质不同,所以把数据安全从存储介质上移除方式会有不同,spec提供了三种通用的移除方法,UFS设备至少支持其中一种。● 对存储的位置进行一次擦除操作。● 对存储的位置使用单一字符(比如0xAA)覆盖写,然后进行擦除。.........

黑猫奥利奥的博客 4075

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

随笔之---java版本哲学家就餐问题【信号量的实现】

很喜欢这样的描述如果你喜欢也不防读一读 从许多许多年前,石头就呆在那座岭上了。△↗那是座无名的低岭,毫不起眼,没有足以称道的风景名胜,那块石头只是许多石头中的一颗,见证过日升日落,经历过沧海桑田,承受四季变迁。黄河水数度从它的身上淹没而过,人群在周围来来去去时,放牛的孩子偶尔也在它的身上歇脚。在许久许久的光阴里,它都没有挪动过位置了 可以收获: 对线程间的同步互斥有更深的理解。 对问题的解决如何抽象到具体转为一个具像的代码流程梳理。这很重要!! 例子可以直接跑起来,直接copy! 问题描述: 哲学家

茄子的博客 699

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

哲学家就餐问题 Java语言实现

1. 哲学家就餐问题描述本文部分内容来源于此,欲了解详细内容,自行点击查看。 为了不失一般性,我们假设有n个哲学家,围着餐桌思考宇宙、人生问题,每个哲学家面前有一个叉子与之对应,即:共有n个叉子;当哲学家思考一段时间后,他会拿起身边的2个叉子才能进食。进食完毕后,该哲学家放下叉子,继续思考人生、宇宙,如此往复,周而复始。 2. 解决方案 在解决该类问题时,属于竞争资源情形,假设所有哲学家均同

toseektruth的博客 2076

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

哲学家就餐问题的思考(java实现)

前言这是我第一眼看到该问题时想到的解决方式之一,不知道可不可行,如果大家有什么看法可以探讨探讨。问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,n进餐完毕,放下筷子又继续思考。约束条件 (1)只有拿到两只筷子时,哲学家

Maxi的专栏 1668

哲学家就餐问题,java实现

这个问题是操作系统中一个经典同步问题,但是我在测试网上各种java实现代码时总感觉有许多错误,用一个简单的测试样例便能快速发现,一般来说,哲学家都设为5,但是这样人工很难根据日志来判断代码是否正确,于是我就娶了个特殊情况,哲学家数量为3,按照题目要求,这个时候同时就餐人数有且只能有一个人,所以我将网上的代码哲学家数量改为3,发现会出现超过一个人同时就餐的情况,与题目要求明显不符,下面就是其中一份代码输出的结果,我特地在输入的地方加上了时间戳,可以更加轻松的判断 哲学家1拿起了左边的筷子 ...

胡七一upup 876

哲学家就餐问题(Java实现信号量和PV操作)

哲学家就餐问题(Java实现信号量和PV操作)

ngczx的博客 708

哲学家就餐问题 java_进程同步——哲学家进餐问题Java实现

importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public class Philosopher implementsRunnable {private static classChopstick {private boolean[] chopsticks = {true, true, ...

weixin_31674039的博客 447

哲学家就餐问题(看完不会你打我)——java实现

定义筷子类定义哲学家类测试使用jconsole检测死锁,发现死锁苏格拉底等待柏拉图,柏拉图等待亚里士多德 ,。。。。

qq_45653382的博客 1237

java哲学家就餐_哲学家就餐的问题--java实现

先来看看运行结果吧:代码分为4个文件:Chopstick.javapackage Philosopher;/*** 表示筷子的类* */public class Chopstick{public Chopstick(){}public Chopstick(int id){this.id = id;}public boolean isAvailable(){return available;}pub...

weixin_29232121的博客 301

Chandy/Misra解法 解决哲学家就餐问题 java实现

Chandy/Misra解法[编辑]1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解法,允许任意的用户(编号P1, …, Pn)争用任意数量的资源。与资源分级解法不同的是,这里编号可以是任意的。 对每一对竞争一个资源的哲学家,新拿一个餐叉,给编号较低的哲学家。每只餐叉都是“干净的”或者“脏的”。最初,所有的餐叉都是脏的。 当一位哲学家要使用资源(也就是要

caizs566205的博客 3137

哲学家就餐问题java实现,死锁经典案例,jconsole检测死锁,依据死锁的必要条件破坏死锁

问题描述 有五位哲学家,围坐在圆桌旁。 他们只做两件事,思考和吃饭,思考一会吃口饭,吃完饭后接着思考。 吃饭时要用两根筷子吃,桌上共有 5 根筷子,每位哲学家左右手边各有一根筷子。 如果筷子被身边的人拿着,自己就得等待。 Synchronized实现方式 package org.sharedmanagement; import lombok.extern.slf4j.Slf4j; @Slf4j(topic = "c.philosopherDining")//日志打印功能注解 publ...

Sold Out 604
上一篇: JDK高性能编程之容器
下一篇: OC中关于类的问题
coderbean
博客等级 码龄11年 12粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值