题目
5 个沉默寡言的哲学家围坐在圆桌前,每人面前一盘意面。叉子放在哲学家之间的桌面上。(5 个哲学家,5 根叉子)
每个哲学家想要吃面得拿起两个叉子。哲学家要么吃面要么思考。
哲学家编号:0-4
思路
这是操作系统里的题目
死锁四个条件:互斥,请求并持有,不可剥夺,循环等待
一般设计程序都是破坏循环等待条件,还有就是超时kill破坏了请求并持有以及让出资源
- 1)同一时间只允许一个人进餐,想要进餐得获得互斥锁
- 2)对上种思路的优化:同一时间允许4个人进餐,Seamphore(4)
- 3)编号奇数为先左手拿叉子,偶数先右手拿叉子
- 4)与思路3类似:除了编号4先右手,其他人全是先拿左手,也就是每个哲学家先拿编号小的叉子
代码
上述四种思路都可以用信号量完成
至多允许4个人同时想进餐
class DiningPhilosophers {
Semaphore semaphore = new Semaphore(4);
Semaphore[] seaps;
public DiningPhilosophers(){
seaps = new Semaphore[5];
for(int i = 0; i < 5; i++){
seaps[i] = new Semaphore(1);
}
}
public void wantsToEat(int philosopher,
Runnable pickLeftFork, //左手拿叉子
Runnable pickRightFork,
Runnable eat, //进餐
Runnable putLeftFork,//左手释放叉子
Runnable putRightFork) throws InterruptedException{
//先获得进餐权限
semaphore.acquire();
//获得叉子
seaps[philosopher].acquire();
seaps[(philosopher + 1) % 5].acquire();
pickLeftFork.run();
pickRightFork.run();
eat.run();
putLeftFork.run();
putRightFork.run();
seaps[(philosopher + 1) % 5].release();
seaps[philosopher].release();
semaphore.release();//注意释放资源顺序与获得顺序相反
} 固定拿叉子顺序
package MultiProcessing;
import java.util.concurrent.Semaphore;
class DiningPhilosophers {
Semaphore[] seaps;
public DiningPhilosophers(){
seaps = new Semaphore[5];
for(int i = 0; i < 5; i++){
seaps[i] = new Semaphore(1);
}
}
public void wantsToEat(int philosopher,
Runnable pickLeftFork,
Runnable pickRightFork,
Runnable eat,
Runnable putLeftFork,
Runnable putRightFork) throws InterruptedException{
int first;
int second;
if(philosopher == 4){
first = (philosopher + 1) % 5;//4号哲学家先拿0号叉子再拿4号叉子
second = philosopher;
}else{
first = philosopher;
second = (philosopher + 1) % 5;
}
seaps[first].acquire();
seaps[second].acquire();
pickLeftFork.run();
pickRightFork.run();
eat.run();
putLeftFork.run();
putRightFork.run();
seaps[second].release();
seaps[first].release();
}
} 
京公网安备 11010502036488号