<br />有五位哲学家,围坐在圆桌旁。
- 他们只做两件事,思考和吃饭,思考一会吃口饭,吃完饭接着思考
- 吃饭时要用两根筷子吃,桌上一共有5根筷子,每位哲学家左右手边各有一根筷子。
- 如果筷子被身边的人拿着,自己就得等待
哲学家模拟代码如下:
其中哲学家创建为线程类,筷子可以视为加锁的资源。
筷子对象在哲学家对象构造时会将其传入,所以可以保证多个线程能够共享筷子对象,从而实现互斥(锁住的是同样的筷子)
public class TestDeadLock {
public static void main(String[] args) {
//创建五根筷子
Chopstick c1 = new Chopstick("1");
Chopstick c2 = new Chopstick("2");
Chopstick c3 = new Chopstick("3");
Chopstick c4 = new Chopstick("4");
Chopstick c5 = new Chopstick("5");
new Philosopher("苏格拉底",c1,c2).start();
new Philosopher("柏拉图",c2,c3).start();
new Philosopher("亚里士多德",c3,c4).start();
new Philosopher("赫拉克利特",c4,c5).start();
new Philosopher("阿基米德",c5,c1).start();
}
}
class Philosopher extends Thread{
//两双筷子
Chopstick left;
Chopstick right;
/*注意这里的筷子对象,在构造时要传入,所以可以保证下边synchronized锁住的是同一个对象*/
public Philosopher(String name,Chopstick left,Chopstick right){
//name传给上层方法
super(name);
this.left=left;
this.right=right;
}
@Override
public void run() {
while (true){//不是吃饭就是睡觉,所以要加while
//尝试获取左筷子
synchronized (left){
//尝试获取右筷子
synchronized (right){
try {
System.out.println(super.getName());
eat();//左右筷子都获得,开始吃饭
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
private static void eat() throws InterruptedException {
System.out.println("eating...");
Thread.sleep(1000);
}
}
class Chopstick{
String name;
public Chopstick(String name){this.name=name;}
@Override
public String toString() {
return super.toString();
}
}
运行一段时间后,会出现死锁现象,每位哲学家各拿一根筷子,同时去争抢其它筷子。