题目
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(); } }