哲学家问题
程序员文章站
2022-07-04 23:34:50
...
描述:五个哲学家围着一张圆桌,每个哲学家面前放着食物。哲学家的生活有两种交替活动:吃饭思考。当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。
解决1:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。设置一个信号量room,使其初始值为4,在哲学家拿起他左边的筷子之前,先对信号量做一次P操作,从而当第五位哲学家去拿做筷子时,room = -1被阻塞,避免了死锁问题。然后当哲学家放下他左边的筷子的时候,就对r做一次V操作。
semaphore chopstick[5]={1,1,1,1,1};
semaphore count=4; // 设置一个count,最多有四个哲学家可以进来
void philosopher(int i)
{
while(true)
{
think();
wait(count); //请求进入房间进餐 当count为0时 不能允许哲学家再进来了
wait(chopstick[i]); //请求左手边的筷子
wait(chopstick[(i+1)%5]); //请求右手边的筷子
eat();
signal(chopstick[i]); //释放左手边的筷子
signal(chopstick[(i+1)%5]); //释放右手边的筷子
signal(count); //退出房间释放信号量
}
}
解决2:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐
public class ThreadTest{
public static void main(String[] args) {
Fork fork = new Fork();
new Philosopher("0", fork).start();
new Philosopher("1", fork).start();
new Philosopher("2", fork).start();
new Philosopher("3", fork).start();
new Philosopher("4", fork).start();
}
}
class Philosopher extends Thread{
private String name;
private Fork fork;
public Philosopher(String name, Fork fork) {
super(name);
this.name = name;
this.fork = fork;
}
@Override
public void run() {
while (true){
thinking();
fork.takeFork();
eating();
fork.putFork();
}
}
public void eating(){
System.out.println("I am Eating:"+name);
try {
sleep(1000);//模拟吃饭,占用一段时间资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void thinking(){
System.out.println("I am Thinking:"+name);
try {
sleep(1000);//模拟思考
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Fork getFork() {
return fork;
}
public void setFork(Fork fork) {
this.fork = fork;
}
}
class Fork{
/*5只筷子,初始为都未被用*/
private boolean[] used={false,false,false,false,false,false};
public synchronized void takeFork(){
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
while(used[i] || used[(i+1)%5]){
try {
wait();//如果左右手有一只正被使用,等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
used[i ]= true;
used[(i+1)%5]=true;
}
public synchronized void putFork(){
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
used[i]= false;
used[(i+1)%5]=false;
notifyAll();//唤醒其他线程
}
}
上一篇: 【PL/SQL】 ROLLBACK WHEN EXECUTE A PROCEDURE Analysis & Output | oracle数据库: 回滚案例的输出与分析
下一篇: 哲学家问题
推荐阅读
-
Android studio 3.0上进行多渠道打包遇到的问题小结(超简洁版)
-
安装多个jdk导致eclipse打不开问题
-
二分法(二):采用二分法解决“最小化最大值问题”
-
Mac Android Studio 3.0 Terminal 中文乱码问题处理
-
二分法(四):采用二分法解决“最大化平均值”问题
-
Android Studio 3.0 新功能全面解析和旧项目适配问题
-
android studio 3.0 升级 项目遇到的问题及更改思路(问题小结)
-
面试官常问的Nginx的几个问题
-
解决Python pandas df 写入excel 出现的问题
-
使用python搭建Django应用程序步骤及版本冲突问题解决