問題描述:一圓桌前坐著5位哲學家,兩個人中間有一只筷子,桌子中央有面條。哲學家思考問題,當餓了的時候拿起左右兩只筷子吃飯,必須拿到兩只筷子才能吃飯。上述問題會產生死鎖的情況,當5個哲學家都拿起自己右手邊的筷子,準備拿左手邊的筷子時產生死鎖現象。
解決辦法:
1、添加一個服務生,只有當經過服務生同意之后才能拿筷子,服務生負責避免死鎖發生。
2、每個哲學家必須確定自己左右手的筷子都可用的時候,才能同時拿起兩只筷子進餐,吃完之后同時放下兩只筷子。
3、規定每個哲學家拿筷子時必須拿序號小的那只,這樣最后一位未拿到筷子的哲學家只剩下序號大的那只筷子,不能拿起,剩下的這只筷子就可以被其他哲學家使用,避免了死鎖。這種情況不能很好的利用資源?!?/p>
代碼實現:實現第2種方案
package cn.edu.sdust.Philosopher;
/*每個哲學家相當于一個線程*/
class Philosopher extends Thread{
private String name;
private Fork fork;
public Philosopher(String name,Fork fork){
super(name);
this.name=name;
this.fork=fork;
}
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void thinking(){
System.out.println("I am Thinking:"+name);
try {
sleep(1000);//模擬思考
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
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) {
// TODO Auto-generated catch block
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();//喚醒其他線程
}
}
//測試
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();
}
}
運行結果:
I am Thinking:0
I am Thinking:2
I am Thinking:3
I am Thinking:1
I am Thinking:4
I am Eating:0
I am Eating:2
I am Thinking:0
I am Eating:4
I am Thinking:2
I am Eating:1
I am Thinking:4
I am Eating:3
I am Thinking:1
I am Eating:0
I am Thinking:3
I am Eating:2
I am Thinking:0
I am Eating:4
I am Thinking:2
分析:上述解決方案解決了死鎖問題??梢钥吹阶疃嘀荒苡袃蓷l相鄰的eating結果,因為每個時刻最多能夠滿足兩個人同時進餐,且兩人座位不相鄰。