您的位置:首页 > 编程语言 > Java开发

课程设计——利用信号量实现哲学家进餐问题(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;
}

}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐