废话不多说 直接上代码
1.筷子类 他有两个属性, 一个是标示这根筷子在哪个哲学家手边,另一个属性标示这个筷子的状态,并且这个状态是随时从内存当中取出的
package com.bjs.dinning;
public class Chopstick {
/**
* 表示筷子是否可用
* */
private volatile boolean available = true;
private int id;
public Chopstick() {
}
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;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "筷子" + id;
}
}
2.筷子数组 动态决定几个哲学家 几根筷子
package com.bjs.dinning;
public class ChopstickArray {
private Chopstick[] chopsticks;
public ChopstickArray() {
}
public ChopstickArray(int size) {
chopsticks = new Chopstick[size];
for (int i = 0; i < chopsticks.length; ++i) {
chopsticks[i] = new Chopstick(i);
}
}
public Chopstick getId(int id) {
return chopsticks[id];
}
public Chopstick getLast(int id) {
if (id == 0) {
return chopsticks[chopsticks.length - 1];
} else {
return chopsticks[id - 1];
}
}
}
3.哲学家类
package com.bjs.dinning;
import java.util.Random;
import javax.swing.JTextArea;
public class Philosopher implements Runnable {
ChopstickArray chopstickArray;
JTextArea eatingTextArea;
private int id;
private boolean state;
JTextArea thinkingTextArea;
JTextArea waitingTextArea;
public Philosopher() {
}
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 eating() {
if (!state) { // 在思考
if (chopstickArray.getId(id).isAvailable()) { // 如果哲学家右手边的筷子可用
if (chopstickArray.getLast(id).isAvailable()) { // 如果左手边的筷子也可用
// 然后将这个能吃饭的哲学家两侧的筷子都设置为不可用
chopstickArray.getId(id).setAvailable(false);
chopstickArray.getLast(id).setAvailable(false);
String text = eatingTextArea.getText();
eatingTextArea.setText(text + this + "在吃饭\n");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
} else {
// 右手边的筷子可用,但是左手边的不可用
String str = waitingTextArea.getText();
waitingTextArea.setText(str + this + "在等待"
+ chopstickArray.getLast(id) + "\n");
try {
wait(new Random().nextInt(100));
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
// 如果哲学家右手边的筷子不可用则等待
String str = waitingTextArea.getText();
waitingTextArea.setText(str + this + "在等待"
+ chopstickArray.getId(id) + "\n");
try {
wait(new Random().nextInt(100));
} catch (Exception e) {
e.printStackTrace();
}
}
}
state = true;
}
@Override
public void run() {
for (int i = 0; i < 10; ++i) {
thinking();
eating();
}
}
public synchronized void thinking() {
if (state) { // 如果在思考,说明这个哲学家两面的筷子没用
chopstickArray.getId(id).setAvailable(true);
chopstickArray.getLast(id).setAvailable(true);
String text = thinkingTextArea.getText();
thinkingTextArea.setText(text + this + "在思考\n");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
state = false;
}
@Override
public String toString() {
return " 哲学家 " + id;
}
}
4.运行的入口类
package com.bjs.dinning;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class DiningPhilosophersFrame extends JFrame{
public DiningPhilosophersFrame(){
panel2.setLayout(new GridLayout(2, 2, 3, 3));
panel2.add(label2);
panel2.add(label3);
panel2.add(label4);
JScrollPane js1 = new JScrollPane(thinkingTextArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JScrollPane js2 = new JScrollPane(eatingTextArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JScrollPane js3 = new JScrollPane(waitingTextArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
panel2.add(js1);
panel2.add(js2);
panel2.add(js3);
panel1.setLayout(new FlowLayout());
panel1.add(label1);
panel1.add(panel2);
panel1.add(button);
setContentPane(panel1);
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
ChopstickArray chopstickArray = new ChopstickArray(3);
for(int i = 0; i < 3; i++){
new Thread(new Philosopher(i, chopstickArray,
thinkingTextArea, eatingTextArea, waitingTextArea))
.start();
}
}
});
setSize(300, 400);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
new DiningPhilosophersFrame();
}
private final JPanel panel1 = new JPanel();
private final JPanel panel2 = new JPanel();
private final JTextArea thinkingTextArea = new JTextArea(5, 10);
private final JTextArea eatingTextArea = new JTextArea(5, 10);
private final JTextArea waitingTextArea = new JTextArea(5, 10);
JLabel label1 = new JLabel("哲学家问题");
JLabel label2 = new JLabel("思考");
JLabel label3 = new JLabel("吃饭");
JLabel label4 = new JLabel("等待");
JButton button = new JButton("开始运行");
}