问题描述:假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗米饭,每两个哲学家之间有一只筷子。假设哲学家必须用两只筷子吃东西。他们只能使用自己左右手边的那两只筷子。哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。
最笨的解决办法:只当哲学家发现左右两边的筷子都可用时,才拿起筷子,否则等待。哲学家编号及筷子编号如下图所示,哲学家i左手边的筷子编号为(i+1)%5,右手边的筷子编号为i。
Chopstick.java
package com.oracle.test6;
public class Chopstick {
public boolean[] isUsing=new boolean[5];
public synchronized void takeChopsticks(int index){
while(isUsing[index]||isUsing[(index+1)%5]){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isUsing[index]=true;
isUsing[(index+1)%5]=true;
System.out.println("哲学家"+index+"拿起筷子");
}
public synchronized void putChopsticks(int index){
isUsing[index]=false;
isUsing[(index+1)%5]=false;
System.out.println("哲学家"+index+"放下筷子");
notify();
}
}
Philosopher.java
package com.oracle.test6;
public class Philosopher implements Runnable{
private int index;
public static Chopstick chop=new Chopstick();
public Philosopher(int index) {
this.index = index;
}
public synchronized void thinking(){
System.out.println("哲学家"+Thread.currentThread().getName()+"在思考");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void eating(){
System.out.println("哲学家"+index+"在吃饭");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
thinking();
chop.takeChopsticks(index);
eating();
chop.putChopsticks(index);
}
}
}
Test.java
package com.oracle.test6;
public class Test {
public static void main(String[] args) {
Philosopher p1=new Philosopher(0);
Philosopher p2=new Philosopher(1);
Philosopher p3=new Philosopher(2);
Philosopher p4=new Philosopher(3);
Philosopher p5=new Philosopher(4);
new Thread(p1,"0").start();
new Thread(p2,"1").start();
new Thread(p3,"2").start();
new Thread(p4,"3").start();
new Thread(p5,"4").start();
}
}