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

合集下载

操作系统课程设计利用多线程和信号量解决哲学家进餐问题java实现

操作系统课程设计利用多线程和信号量解决哲学家进餐问题java实现

操作系统课程设计利用多线程和信号量解决哲学家进餐问题j a v a实现IMB standardization office【IMB 5AB- IMBK 08- IMB 2C】操作系统课程设计课程设计报告课题:利用信号量和多线程机制实现“哲学家进餐”问题所在学院:信息工程学院班级:计科1201学号:4姓名:魏祥指导教师:徐向英2015年1月 1日目录一、课程设计目标 (3)二、课题内容 (3)三、设计思路 (3)四、源代码 (5)五、运行与测试 (9)六、心得体会 (10)一、课程设计目标学习多线程编程,使用线程的同步机制实现“哲学家进餐”问题。

具体要求:1.创建POSIX线程,实现多线程的并发执行,验证多线程共享进程资源的特性。

2.使用互斥量和条件变量,或使用信号量实现线程的同步互斥。

3.验证“哲学家进餐”问题中的死锁情况,并加以解决。

二、课题内容哲学家进餐问题由Dijkstra提出,问题描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,他们的生活方式是交替地进行思考和进餐。

平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。

进餐完毕,放下筷子继续思考。

本次课题要求使用多线程和信号量解决哲学家进餐问题。

并演示产生死锁的情况。

三、设计思路经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许以为哲学家使用。

为了实现对筷子的互斥,可以用一个信号量表示一只筷子,由着五个信号量构成信号量数组。

当哲学家饥饿时总是先去拿左筷子,成功后在拿右筷子。

当五位哲学家同时拿起左筷子,这是每位哲学家都没有右筷子可以拿,就会造成死锁。

思路1:利用记录型信号量设置值为4的记录型信号量,至多只允许四位哲学家同时去拿左筷子().acquire()),只有拿到左筷子,才能继续拿右筷子().acquire())。

拿到两双筷子之后便可以用餐,用餐完毕,先放下左筷子().release()),再放下右筷子().release())。

用Java的Guarded Suspension模式解决哲学家进餐问题

用Java的Guarded Suspension模式解决哲学家进餐问题

2 哲 学 家 进 餐 问题
哲 学家 进餐 问题 是一 个典 型 的 同步 问题 . 这个 问题 由 Djsa 出 : i t提 kr 五个 哲学 家 围坐在一 张 圆桌 周 围 , 们 的生 活方 式是 交替 地进 行思考 和进 餐 . 上有 五支 筷子 ,每两 个哲 学 家 之间 放 一支 . 学 家饥 他 桌 哲
维普资讯
洛 阳师 范 学 院 学 报 2 0 0 6年 第 2期
・ 1・ 9
用 Jv a a的 Gu r e up nin模 式 解 决 ad dS se s o
哲 学 家 进餐 问题
曹建 立 ,周 震
( 阳师范学 院, 洛 河南 洛阳 4 12 ) 7 02
任 务 的机 制 .
地 支 持 多线 程机 制 , 以方便 地生 成多 线程应 用程 序 , 可 而且 运行 环 境也 利 用 多线程 的技术 并 发 提供 多 项服 务 , “ 圾 ” 如 垃 回收 .aa 言 中提供 了 T ra Jv 语 hed类 ,在类 中封 装 了许 多关 于线 程操 作 的方法 ,如线
程的启动、 运行 、 休眠、 挂起、 恢复 、 退出和终止以及对线程优先级的控制. 并提供 了 s cr i d y h n e 关键 n oz
字来 处 理线 程之 间 的共享 互斥 问题 .
1 2 Gu r e up n in模式 . addS ses o
在该模式下 , 当某个线程对临界资源进行访问时 , 首先需要判断临界资源 的警戒条件是否成立 , 如果成立 , 则可以进行访问; 否则 , 该线程就会执行 w i进入临界资源的等待区( as ) a t w ie 被阻塞起来 , tt 直到 其 他 的线程 改变 了 临界资 源 的状态 , 临界 资源 的警 戒 条件成 立后 , 用 nty l将其 唤 醒. 使 才 of l iA

Java线程同步问题--哲学家就餐

Java线程同步问题--哲学家就餐

Java线程同步问题--哲学家就餐⽬录1.场景2.解决⽅案⽅法⼀:限制吃饭的哲学家⼈数⽅法⼆:找到⼀个左撇⼦哲学家1.场景有五位沉默的哲学家围坐在⼀张圆桌旁,他们⼀⽣都在吃东西和思考。

有五只筷⼦供他们使⽤,哲学家需要双⼿拿到⼀双筷⼦之后才能吃饭;吃完后会将筷⼦放下继续思考。

那么现在有⼀个问题,我们需要想出⼀种⽅案,如何保证哲学家们可以交替吃饭和思考,⽽不会被饿死。

上⾯这个问题是由Dijkstra提出的⼀个经典的线程同步问题。

2.解决⽅案我们在开始想如何解决问题之前,可以先将这个场景通过代码还原,在程序中进⾏建模。

每⼀只筷⼦可以看做是⼀个资源数据,都可以被它两边的哲学家尝试去获取,并且同⼀时间只能由其中⼀⼈持有,这可以通过我们JUC包中的信号量Semaphore来表⽰。

然后,每个哲学家可以看做是⼀个线程,每个线程中的run⽅法内容都是先进⾏思考,然后试图获取左右两边的筷⼦吃饭,吃完饭后继续思考。

通过上⾯的分析,我们的代码实现如下:/*** @author ⼩⿊说Java* @ClassName DiningPhilosophers* @Description 哲学家就餐问题* @date 2022/2/6**/@Slf4jpublic class DiningPhilosophers implements Runnable {private final int id;public DiningPhilosophers(int id) {this.id = id;}private static final Random random = new Random(System.currentTimeMillis());private static final Semaphore[] forks = new Semaphore[5];// 初始化信号量,每个信号量为1,代表1只筷⼦static {forks[0] = new Semaphore(1);forks[1] = new Semaphore(1);forks[2] = new Semaphore(1);forks[3] = new Semaphore(1);forks[4] = new Semaphore(1);}@Overridepublic void run() {try {while (true) {think();eat(id);}} catch (InterruptedException e) {log.error("异常中断", e);}}/*** 哲学家思考随机时间*/private void think() throws InterruptedException {LISECONDS.sleep(random.nextInt(100));}private void eat(int id) {// TODO}}接下来,我们思考⼀下,如何实现哲学家吃饭的逻辑。

操作系统课程设计——哲学家进餐问题

操作系统课程设计——哲学家进餐问题

操作系统课程设计——哲学家进餐问题1000字哲学家进餐问题是一个经典的多线程同步问题,在操作系统中有着广泛的应用。

因此,在操作系统课程设计中,探究哲学家进餐问题是一件非常有意义的事情。

哲学家进餐问题的场景是:五个哲学家围坐在一张圆桌前,每个哲学家的左右两侧有一只筷子,他们需要利用这两只筷子才能进餐。

每个哲学家有两种状态:思考和进餐。

当一个哲学家处于进餐状态时,他需要同时获取他左右两侧的筷子,进餐结束后,他会释放这两只筷子,进入思考状态。

在这个场景中,如果所有的哲学家都同时想要进餐,那么就可能会出现死锁情况,即所有的哲学家都拿到了左手边的筷子,但都无法拿到右手边的筷子,导致无法进餐。

因此,需要在代码中实现同步互斥机制,避免死锁的发生。

本课程设计中,我使用了Java语言来实现哲学家进餐问题。

在代码实现中,首先定义了哲学家、筷子、餐桌等对象,然后使用线程来模拟哲学家的思考和进餐过程。

为了避免死锁,我使用了Chandy/Misra算法,即每个哲学家先尝试去取左手边的筷子,如果取不到就不再继续等待,而是重新回到思考状态,等待下一个机会。

同时,当一个哲学家取到了左手边的筷子之后,如果发现右手边的筷子已被占用,他就会释放左手边的筷子,重新回到思考状态,等待下一个机会。

在实现过程中,我还使用了信号量机制,保证了线程间的同步互斥。

每个筷子都是一个二元信号量,初始为1,表示可用。

当一个哲学家拿起筷子时,他会将对应的信号量减1,表示不可用。

当哲学家用完筷子之后,会将对应的信号量加1,表示可用。

通过这种方式,实现了对筷子的访问同步。

最后,我对代码进行了测试,模拟了多位哲学家同时进行进餐的过程。

在测试中,我发现哲学家进餐的速度受到筷子的数量和哲学家思考进餐比例的影响。

当筷子数量少于哲学家数量时,容易出现死锁;当哲学家思考和进餐的时间相当时,程序的运行情况比较稳定。

总的来说,本课程设计实现了哲学家进餐问题,通过学习该问题,我更深入地理解了同步互斥机制的重要性,并学会了如何使用信号量来实现同步互斥。

操作系统课程设计利用多线程和信号量解决哲学家进餐问题java实现

操作系统课程设计利用多线程和信号量解决哲学家进餐问题java实现

操作系统课程设计课程设计报告课题:利用信号量和多线程机制实现“哲学家进餐”问题所在学院:信息工程学院班级:计科1201学号:121404114姓名:魏祥指导教师:徐向英2015年1月1日目录一、课程设计目标 (3)二、课题内容 (3)三、设计思路 (3)四、源代码 (5)五、运行与测试 (9)六、心得体会 (10)一、课程设计目标学习多线程编程,使用线程的同步机制实现“哲学家进餐”问题。

具体要求:1.创建POSIX线程,实现多线程的并发执行,验证多线程共享进程资源的特性。

2.使用互斥量和条件变量,或使用信号量实现线程的同步互斥。

3. 验证“ 哲学家进餐”问题中的死锁情况,并加以解决。

二、课题内容哲学家进餐问题由Dijkstra提出,问题描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,他们的生活方式是交替地进行思考和进餐。

平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。

进餐完毕,放下筷子继续思考。

本次课题要求使用多线程和信号量解决哲学家进餐问题。

并演示产生死锁的情况。

三、设计思路经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许以为哲学家使用。

为了实现对筷子的互斥,可以用一个信号量表示一只筷子,由着五个信号量构成信号量数组。

当哲学家饥饿时总是先去拿左筷子,成功后在拿右筷子。

当五位哲学家同时拿起左筷子,这是每位哲学家都没有右筷子可以拿,就会造成死锁。

思路1:利用记录型信号量设置值为4的记录型信号量,至多只允许四位哲学家同时去拿左筷子(leftStick.getSema().acquire()),只有拿到左筷子,才能继续拿右筷子(rightStick.getSema().acquire())。

拿到两双筷子之后便可以用餐,用餐完毕,先放下左筷子(leftStick.getSema().release()),再放下右筷子(rightStick.getSema().release())。

利用Java高级别并发对象求解哲学家进餐问题

利用Java高级别并发对象求解哲学家进餐问题
/ / D i n i n g P h i l o s ph o e r s 5 . j a v a i m p o r t j a v a . u t 1 f . c o n c m ' r e n t . 1 o c k s . ;
i m p o r t j a v a . u t i l . c o n c u r r e n t .・:
S e m a p h o r e : c h o p s t i c k [ 0 ] = c h o p s t i c k [ 1 ] =c h o p s t i c k [ 2 ] = c h ps o t i c k
[ 3 ] = c h o p s t i c k [ 4 ] = 1
1 哲 学 家 进 餐 问题 的 一 种解 法
哲学家进餐问题有很多解法 , 其中的一种解法 是 只有 当哲 学 家 可 以 同时 获 得 两 个 筷 子 ( 临 界 资 源) 时, 才允许哲学家拿起筷子进餐 . 这 种 解 法 的 实质是预先分配哲学家需要的全部资源, 从而预防 死锁 的发 生. 算法 描述 如下 :
V ( c h o p s t i c k [ i ] ) ; V( c h o p s t i c k [ ( i +1 ) %5 } ;
唤醒 P h i o a ph o e r( i + 4 ) %5 ;
唤醒 P h i o s ph o e r( i +1 ) %5 ;
c o n d i t i o n [ j ] = l o c k . n e w C o n d i i t o n ( ) ;
第3 1卷 第 6期
2 0 1 3 年 1 1月
佳 木 斯 大 学 学 报 ( 自 然 科 学 版 )

试验1-哲学家就餐问题

试验1-哲学家就餐问题

实验2. 类、对象、继承及多态实验目的:理解Java对象的面向对象的特征以及在编程中的应用。

实验内容:1、验证对象作为参数传递是引用传递,而普通数据类型为值传递。

2、验证构造方法和静态属性与方法专属于类,而其他属性和方法虽然在类中定义,但是为对象而定义。

3、验证子类对象实例化时,通过继承,不仅将public、protected、缺省的属性和方法拷贝到对象当中,也将父类的私有属性拷贝到对象当中。

4、编写程序,体会类在重载情况下的相互调用,体会构造方法重载的调用方式。

5、编程体现this的三种用法,super的两种用法,指出this.属性在什么情况下不可以省略,指出super.成员方法在什么情况下不能省略,指出this指代对象的作用。

6、设计Src和Dis两个类, Src中有一个被封装的属性,类型为int(要求为非负值),每当我们通过特定方法更改Src对象中的这个属性后,Dis对象都能得到通知,并向Src发消息获得此属性值实验要求:1、程序以能证明和说明实验内容当中提出的问题为实现标准。

2、程序应有良好的书写规范,在类名定义、包名定义、变量定义、常量定义上遵从规范,同时程序在书写上应有良好的缩进层次。

3、实验报告中应有实验体会和收获等方面。

准备工具:1、JDK1.3以上版本,设置环境变量,搭建编译和运行环境。

1、搭建环境。

2、选用Application进行验证。

实验3. 多线程综合设计实验目的:理解Java语言中的多线程和异常处理,并将二者结合起来设计一个综合程序,实现特定的应用功能。

实验内容:1、7名哲学家同桌就餐,演示哲学家就餐问题中死锁现象的出现,并说明原因2、给出一种解决方案,保证多线程下不出现死锁,并说明这样实现的理由实验要求:1、必须有多线程和异常的内容,其中多线程需要处理多线程同步,如还有同步通信则更好;异常需要有异常抛出、异常捕获、异常嵌套捕获等内容,如有自定义异常类则更好。

2、程序当中产生异常的点很多,在一个大的应用程序当中(有众多的类),无论哪种异常发生后,如何集中在一处统一给出中文提示。

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

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

哲学家就餐的问题--java实现先来看看运⾏结果吧:代码分为4个⽂件:Chopstick.javapackage Philosopher;/*** 表⽰筷⼦的类* */public class Chopstick{public Chopstick(){}public Chopstick(int id){this.id = id;}public boolean isAvailable(){return available;}public void setAvailable(boolean available){this.available = available;}public int getId(){return id;}public void setId(int id){this.id = id;}@Overridepublic String toString(){return "筷⼦" + id;}/*** 表⽰筷⼦是否可⽤* */private volatile boolean available = true;private int id;} ChopstickArray.javapackage Philosopher;public class ChopstickArray{public ChopstickArray(){}public ChopstickArray(int size){chopsticks = new Chopstick[size];for(int i = 0; i < chopsticks.length; ++i){chopsticks[i] = new Chopstick(i);}}public Chopstick getId(int id){return chopsticks[id];}public Chopstick getLast(int id){if(id == 0){return chopsticks[chopsticks.length - 1];}else{return chopsticks[id - 1];}}private Chopstick[] chopsticks;}DiningPhilosophersFrame.javapackage Philosopher;import java.awt.FlowLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;public class DiningPhilosophersFrame extends JFrame{public DiningPhilosophersFrame(){panel2.setLayout(new GridLayout(2, 2, 3, 3));panel2.add(label2);panel2.add(label3);panel2.add(label4);JScrollPane js1 = new JScrollPane(thinkingTextArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane js2 = new JScrollPane(eatingTextArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane js3 = new JScrollPane(waitingTextArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);panel2.add(js1);panel2.add(js2);panel2.add(js3);panel1.setLayout(new FlowLayout());panel1.add(label1);panel1.add(panel2);panel1.add(button);setContentPane(panel1);button.addActionListener(new ActionListener(){@Overridepublic void actionPerformed(ActionEvent e){ChopstickArray chopstickArray = new ChopstickArray(5); for(int i = 0; i < 5; i++){new Thread(new Philosopher(i, chopstickArray,thinkingTextArea, eatingTextArea, waitingTextArea)) .start();}}});setSize(300, 400);setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }public static void main(String[] args){new DiningPhilosophersFrame();}private final JPanel panel1 = new JPanel();private final JPanel panel2 = new JPanel();private final JTextArea thinkingTextArea = new JTextArea(5, 10);private final JTextArea eatingTextArea = new JTextArea(5, 10);private final JTextArea waitingTextArea = new JTextArea(5, 10);JLabel label1 = new JLabel("哲学家问题");JLabel label2 = new JLabel("思考");JLabel label3 = new JLabel("吃饭");JLabel label4 = new JLabel("等待");JButton button = new JButton("开始运⾏");} Philosopher.javapackage Philosopher;import java.util.Random;import javax.swing.JTextArea;public class Philosopher implements Runnable{public Philosopher(){}public Philosopher(int id, ChopstickArray chopstickArray,JTextArea thinkingTextArea, JTextArea eatingtextArea,JTextArea waitingTextArea){this.id = id;this.chopstickArray = chopstickArray;this.thinkingTextArea = thinkingTextArea;this.eatingTextArea = eatingtextArea;this.waitingTextArea = waitingTextArea;}public synchronized void thinking(){if(state){ // 如果在思考,说明这个哲学家两⾯的筷⼦没⽤chopstickArray.getId(id).setAvailable(true);chopstickArray.getLast(id).setAvailable(true);String text = thinkingTextArea.getText();thinkingTextArea.setText(text + this + "在思考\n");try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}}state = false;}public synchronized void eating(){if(!state){ // 在思考if(chopstickArray.getId(id).isAvailable()){ // 如果哲学家右⼿边的筷⼦可⽤ if(chopstickArray.getLast(id).isAvailable()){ // 如果左⼿边的筷⼦也可⽤ // 然后将这个能吃饭的哲学家两侧的筷⼦都设置为不可⽤chopstickArray.getId(id).setAvailable(false);chopstickArray.getLast(id).setAvailable(false);String text = eatingTextArea.getText();eatingTextArea.setText(text + this + "在吃饭\n");try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}}else{// 右⼿边的筷⼦可⽤,但是左⼿边的不可⽤String str = waitingTextArea.getText();waitingTextArea.setText(str + this + "在等待"+ chopstickArray.getLast(id) + "\n");try{wait(new Random().nextInt(100));}catch(Exception e){e.printStackTrace();}}}else{// 如果哲学家右⼿边的筷⼦不可⽤则等待String str = waitingTextArea.getText();waitingTextArea.setText(str + this + "在等待"+ chopstickArray.getId(id) + "\n");try{wait(new Random().nextInt(100)); }catch(Exception e){e.printStackTrace();}}}state = true;}@Overridepublic void run(){for(int i = 0; i < 10; ++i){thinking();eating();}}@Overridepublic String toString(){return " 哲学家 " + id;}private int id;private boolean state;ChopstickArray chopstickArray;JTextArea thinkingTextArea;JTextArea eatingTextArea;JTextArea waitingTextArea;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档