多线程Demo学习(哲学家就餐问题)
一.哲学家就餐问题
为了快速进入状态我们先来复习下哲学家问题:
有5个哲学家去吃中餐,坐在一张圆桌上,他们旁边有五只筷子(每两个人中间放一根),哲学家们时而思考,时而吃饭,但每个人都需要一双筷子才能吃饭,并且在吃完后将筷子放回原处接着思考。
这里就有一个问题:我们都知道这五个哲学家不可能同时吃饭,如果他们尝试同时去同时拿筷子,他们每个人只能拿到一个筷子,并且每个人都在等待别人放下手中的筷子,这样他们都会饿死(因为他们都吃不到东西)。 这就是一种死锁。
那么怎样才能让五个哲学家都能吃到东西呢? 这就是我们下面学习例子的精髓:
1.首先我们先了解下代码:
下面的类是筷子类,属性有 筷子id和 筷子的可用状态:
public class Chopstick {
private int id;
private volatile boolean available = true;
public Chopstick(int id) {
this.id = id;
}
public int getId() {
return id;
}
public boolean isAvailable() {
return available;
}
public void setAvailable(boolean available) {
this.available = available;
}
@Override
public String toString() {
return "筷子 " + id;
}
}
下面的类是筷子数组类,它用于存储多个筷子,用来表示桌子上的所有筷子:
public class ChopstickArray {
private Chopstick[] chopsticks;
public ChopstickArray(int size) {
chopsticks = new Chopstick[size];
for (int i = 0; i < chopsticks.length; i++) {
chopsticks[i] = new Chopstick(i);
}
}
public Chopstick get(int id) {
return chopsticks[id];
}
public Chopstick getLast(int id) {
if (id == 0) {
return chopsticks[chopsticks.length - 1];
} else {
return chopsticks[id - 1];
}
}
}
下面的类是哲学家类:里面定义的哲学家任务和一些属性
import java.util.Random;
import javax.swing.JTextArea;
//哲学家任务
public class Philosopher implements Runnable {
private int id;//哲学家id
private ChopstickArray chopstickArray;//筷子数组对象
private boolean state;//状态
private JTextArea thinkingTextArea;
private JTextArea eatingTextArea;
private JTextArea waitingTextArea;
public Philosopher(int id, ChopstickArray chopstickArray, JTextArea thinkingTextArea, JTextArea eatingTextArea, JTextArea waitingTextArea) {
this.id = id;
this.chopstickArray = chopstickArray;
this.thinkingTextArea = thinkingTextArea;
this.eatingTextArea = eatingTextArea;
this.waitingTextArea = waitingTextArea;
}
public synchronized void thinking() {
if (state) {
chopstickArray.get(id).setAvailable(true);
chopstickArray.getLast(id).setAvailable(true);
String text = thinkingTextArea.getText();
thinkingTextArea.setText(text + this + " 在思考\n");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
state = false;
}
public synchronized void eating() {
if (!state) {
// state是一个布尔值,true表示哲学家刚才的状态是吃饭,false表示思考
if (chopstickArray.get(id).isAvailable()) {
// 如果哲学家右手边的筷子可用
if (chopstickArray.getLast(id