1 前言
哲学家问题是常见的问题,描述的是5个科学家在一餐桌吃饭,他们每个人的左右都有一只筷子。只有当他们拿到两只筷子时候才能吃饭。
这个题的本质就是对锁的练习,每只筷子相当于一把锁,只有获得两把锁(筷子)才能进行吃饭。
常见方法:
1、每个科学家拿左手边的筷子,肯定会发生死锁。
2、从时间考虑(锁释放),或者优先级考虑一般是不对的。
2 正确解法
- 如果一个人是先获得右手边的筷子,这时候其左手边的筷子就空闲出来了,其他人就可以获得进行吃饭。
- 更高效的解法:可以让两位科学家先获得其右边的筷子,其他科学家获得左边的筷子。
package cn.itcast.n6.c1;
import lombok.SneakyThrows;
/**
* @author : msf
* @date : 2022/12/4
*/
public class CoderLunch {
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);
Coder coder1 = new Coder("张三", c1, c2, 1);
Coder coder2 = new Coder("李四", c2, c3, 2);
Coder coder3 = new Coder("王五", c3, c4, 3);
Coder coder4 = new Coder("赵六", c4, c5, 4);
Coder coder5 = new Coder("田七", c5, c1, 5);
coder1.start();
coder2.start();
coder3.start();
coder4.start();
coder5.start();
}
}
class Coder extends Thread {
private Chopstick left;
private Chopstick right;
private int index;
public Coder(String name, Chopstick left, Chopstick right, int index) {
this.setName(name);
this.left = left;
this.right = right;
this.index = index;
}
@Override
public void run() {
if (index % 2 == 0) {
synchronized (left) {
synchronized (right) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "程序员拿到了" + left.getId() + "和" + right.getId() + "筷子已经吃过饭了");
}
}
} else {
synchronized (right) {
synchronized (left) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "程序员拿到了" + left.getId() + "和" + right.getId() + "筷子已经吃过饭了");
}
}
}
}
}
class Chopstick {
private int id;
public Chopstick(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}