课程设计——利用信号量实现哲学家进餐问题(JAVA)

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;
    }
 
}

 

posted @ 2017-06-29 13:57  douzujun  阅读(2700)  评论(1编辑  收藏  举报