课程设计——利用信号量实现哲学家进餐问题(JAVA)
2017-06-29 13:57
841 查看
package cn.Douzi.PhiEat; /** * 表示筷子的类 */ public class Chopstick{ /** * 表示筷子是否可用 */ private volatile boolean available = true; private int id; 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; } }
package cn.Douzi.PhiEat; 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]; } //得到 编号id的筷子 public Chopstick getLast(int id){ if(id == 0){ return chopsticks[chopsticks.length - 1]; }else{ return chopsticks[id - 1]; } } }
package cn.Douzi.PhiEat; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DiningPhilosophersFrame extends JFrame{ private final JPanel panel1 = new JPanel(); private final JPanel panel2 = new JPanel(); private final JPanel panel3 = new JPanel(); private final JTextArea thinkingTextArea = new JTextArea(6, 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("等待"); JLabel space = new JLabel(" "); JButton button = new JButton("开始运行"); JButton stop = new JButton("暂停"); public DiningPhilosophersFrame(){ panel2.setLayout(new GridLayout(2, 2, 3, 3)); panel3.setLayout(new BorderLayout()); label2.setFont(new Font("隶书", 0, 30)); label2.setHorizontalAlignment(0); label3.setFont(new Font("隶书", 0, 30)); label3.setHorizontalAlignment(0); label4.setFont(new Font("隶书", 0, 30)); label4.setHorizontalAlignment(0); panel2.add(label2); panel2.add(label3); panel2.add(label4); thinkingTextArea.setEditable(false); eatingTextArea.setEditable(false); waitingTextArea.setEditable(false); 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); // panel2.add(label2); // panel2.add(label3); // panel2.add(label4); panel2.setBackground(Color.LIGHT_GRAY); panel1.setBackground(Color.LIGHT_GRAY); panel1.setLayout(new FlowLayout(FlowLayout.CENTER)); label1.setFont(new Font("隶书", 0, 50)); //标题字体 panel1.add(label1); panel1.add(panel2); button.setBackground(Color.ORANGE); stop.setBackground(Color.ORANGE); panel1.add(button); panel1.add(space); panel1.add(stop); 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(); } } }); stop.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub try { Thread.sleep(3000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); setTitle("可爱的豆豆"); setSize(450, 400); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args){ new DiningPhilosophersFrame(); } }
package cn.Douzi.PhiEat; import java.util.Random; import javax.swing.JTextArea; public class Philosopher implements Runnable{ private int id; private boolean state; ChopstickArray chopstickArray; JTextArea thinkingTextArea; JTextArea eatingTextArea; 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 thinking() { if(state) { // 如果在思考,说明这个哲学家两面的筷子没用 chopstickArray.getId(id).setAvailable(true); chopstickArray.getLast(id).setAvailable(true); String text = thinkingTextArea.getText(); thinkingTextArea.setText(text + this + "在思考\n"); thinkingTextArea.setCaretPosition(thinkingTextArea.getDocument().getLength()); thinkingTextArea.paintImmediately(thinkingTextArea.getBounds()); 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"); eatingTextArea.setCaretPosition(eatingTextArea.getDocument().getLength()); eatingTextArea.paintImmediately(eatingTextArea.getBounds()); 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"); waitingTextArea.setCaretPosition(waitingTextArea.getDocument().getLength()); waitingTextArea.paintImmediately(waitingTextArea.getBounds()); 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; } }
相关文章推荐
- 课程设计——利用信号量实现生产者-消费者问题(java)
- 课程设计——利用信号量实现读-写者问题(JAVA)
- 哲学家进餐问题,java实现
- Java总结(十)—实现Runnable接口创建线程,线程安全同步,死锁(哲学家进餐问题),读写锁
- Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)
- 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题
- Java实现哲学家进餐问题
- java实现哲学家进餐问题,及其死锁问题的解决
- java 多线程实现 哲学家进餐问题
- Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)
- 哲学家进餐问题与生产者与消费者问题(java实现)
- 通过生产者消费者问题比较信号量和信号【Java实现】
- Java中利用synchronized关键字实现多线程同步问题
- 利用信号量和PV操作实现进程互斥和同步问题
- 操作系统算法:如何利用信号量实现优先级(从读者写者问题引发的联想)
- Java课程设计 矩阵类 实现加、减、乘法
- 关于网宿厦门研发中心笔试的一道PV操作题:利用java中的多线程实现生产者与消费者的同步问题
- Java课程作业-利用RMI实现文件传输
- (总结)JAVA课程设计报告:记事本的设计与实现
- linux网络编程之System V 信号量(二):用信号量实现进程互斥示例和解决哲学家就餐问题