先来看看运行结果吧:
代码分为4个文件:
Chopstick.java
package Philosopher; /** * 表示筷子的类 * */ public class Chopstick{ public Chopstick(){ } public Chopstick(int id){ this.id = id; } public boolean isAvailable(){ return available; } public void setAvailable(boolean available){ this.available = available; } public int getId(){ return id; } public void setId(int id){ this.id = id; } @Override public String toString(){ return "筷子" + id; } /** * 表示筷子是否可用 * */ private volatile boolean available = true; private int id; }
ChopstickArray.java
package Philosopher; public class ChopstickArray{ 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]; } } private Chopstick[] chopsticks; }
DiningPhilosophersFrame.java
package Philosopher; 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(5); for(int i = 0; i < 5; 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("开始运行"); }
Philosopher.java
package Philosopher; import java.util.Random; import javax.swing.JTextArea; public class Philosopher implements Runnable{ 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 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; } 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(); } } @Override public String toString(){ return " 哲学家 " + id; } private int id; private boolean state; ChopstickArray chopstickArray; JTextArea thinkingTextArea; JTextArea eatingTextArea; JTextArea waitingTextArea; }