import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.ImageIcon;
//////////////////////////////////////////////////
//筷子类
class Bamboo {
boolean bState; //互斥信号量
JLabel bLabel; //显示筷子的JLabel
ImageIcon emptyImage,bambooImage; //被用时为empty图片,否则为筷子图片
public Bamboo(JLabel bLabel, ImageIcon image) {
emptyImage=new ImageIcon("空的.jpg");
this.bLabel=bLabel;
this.bambooImage=image;
bState=true; //一开始都设筷子为可用状态
}
public synchronized void gainBamboo() {
while(!bState) { //如果此筷子已被用,则等待
try {
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
bLabel.setIcon(emptyImage); //获得筷子,并把筷子所代表 的图片设为空
bState=false; //把此筷子的状态设为已被用了
}
public synchronized void takeBamboo() { //放下筷子,把筷子状态设为可用
bState=true;
bLabel.setIcon(bambooImage);
notify(); //唤醒其他在等待的线程,如果有等待此筷子的线程,则可以继续判断
}
}
//////////////////////////////////////////////////////////
//哲学家类,
class Zexuejia extends Thread {
int thinkSpeed, eatSpeed; // 思考,吃饭的时间
Bamboo left, right; // 哲学家的左右筷子
int num; // 第几号哲学家
JLabel zxjLable, leftLable, rightLable, zxjLeftLabel, zxjRightLabel; // zxjLable为哲学家设置状态的,
// leftLable,rightLable,为哲学家的左右两根,
// zxjLeftLabel,zxjRightLabel为哲学家拿起两筷子后的
ImageIcon leftImage, rightImage; //左右两个筷子的图片
Zexuejia(int num, JLabel zLabel, Bamboo left, JLabel lLabel,
Bamboo right, // 哲学家构造函数
JLabel rLabel, ImageIcon lImage, ImageIcon rImage, JLabel zLLabel,
JLabel zRLabel) {
this.num = num;
this.zxjLable = zLabel;
this.left = left;
this.leftLable = lLabel;
this.right = right;
this.rightLable = rLabel;
this.leftImage = lImage;
this.rightImage = rImage;
this.zxjRightLabel = zRLabel;
this.zxjLeftLabel = zLLabel;
}
public void run() {
ImageIcon thinkImage = new ImageIcon("thinking.gif");
ImageIcon huangryImage = new ImageIcon("huangry.gif");
ImageIcon eatImage = new ImageIcon("eating.gif");
ImageIcon empty = new ImageIcon("empty.jpg");
while (true) {
zxjLable.setIcon(thinkImage);
do {
thinkSpeed = (int) (Math.random() * 10000); // 获得随机的思考时间
} while (thinkSpeed < 1500);
try {
sleep(thinkSpeed); // 以线程睡眠的方式让哲学家思考一些时间
} catch (Exception e) {
}
zxjLable.setIcon(huangryImage);
left.gainBamboo(); // 获得左边的筷子
zxjLeftLabel.setIcon(leftImage);
right.gainBamboo(); // 获得右边的筷子
zxjRightLabel.setIcon(rightImage);
zxjLable.setIcon(eatImage);
do {
eatSpeed = (int) (Math.random() * 10000); // 获得随机的吃饭时间
} while (eatSpeed < 1500);
try {
sleep(eatSpeed); // 以线程睡眠的方式让哲学家吃饭一些时间
} catch (Exception e) {
}
synchronized (left) {
left.takeBamboo(); // 放下左边的筷子
zxjLeftLabel.setIcon(empty);
}
synchronized (right) {
right.takeBamboo(); // 放下右边的筷子
zxjRightLabel.setIcon(empty);
}
}
}
}
public class ZxjFrame extends JFrame implements ActionListener {
JButton start_Button,end_Button;
JLabel bambooLabel[];
JLabel h[];
JLabel zxjLable[];
Bamboo bamboo[]; // 筷子对象数组
Zexuejia zxj[]; // 哲学家对象数组
ImageIcon bambooImage[],empty,thinkImage,huangryImage,eatImage;
ZxjFrame()
{ // 构造函数
super("---经典哲学家就餐问题模拟---周辉强--3105007364--软件工程(3)班----");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container ct=this.getContentPane();
ct.setBackground(java.awt.Color.WHITE);
thinkImage=new ImageIcon("thinking.gif");
huangryImage=new ImageIcon("huangry.gif");
eatImage=new ImageIcon("eating.gif");
empty=new ImageIcon("空的.gif");
JPanel panel=new JPanel();
panel.setLayout(new FlowLayout());
zxjLable=new JLabel[6];
for(int i=1;i<=5;i++) {
zxjLable[i]=new JLabel();
zxjLable[i].setIcon(thinkImage); //一开始设为思考
}
bambooImage=new ImageIcon[6];
bambooImage[1]=new ImageIcon("bamboo.gif");
bambooImage[2]=new ImageIcon("bamboo.gif");
bambooImage[3]=new ImageIcon("bamboo.gif");
bambooImage[4]=new ImageIcon("bamboo.gif");
bambooImage[5]=new ImageIcon("bamboo.gif");
bambooLabel=new JLabel[6];
bambooLabel[1]=new JLabel(); bambooLabel[1].setIcon(bambooImage[1]);
bambooLabel[2]=new JLabel(); bambooLabel[2].setIcon(bambooImage[2]);
bambooLabel[3]=new JLabel(); bambooLabel[3].setIcon(bambooImage[3]);
bambooLabel[4]=new JLabel(); bambooLabel[4].setIcon(bambooImage[4]);
bambooLabel[5]=new JLabel(); bambooLabel[5].setIcon(bambooImage[5]);
bamboo=new Bamboo[6];
for(int i=1;i<=5;i++) bamboo[i]=new Bamboo(bambooLabel[i],bambooImage[i]); //筷子对象的初始化
h=new JLabel[13];
for(int i=1;i<=12;i++) {
h[i]=new JLabel();
h[i].setIcon(empty);
}
zxj=new Zexuejia[6];
panel=new JPanel();
panel.setLayout(new GridBagLayout());
//GridBagLayout 类是一个灵活的布局管理器,
//它不要求组件的大小相同即可将组件垂直和水平对齐。
//每个 GridBagLayout 对象维持一个动态的矩形单元网格,
//每个组件占用一个或多个这样的单元,称为显示区域。
GridBagConstraints gbc=new GridBagConstraints();
//GridBagConstraints 类指定使用 GridBagLayout 类布置的组件的约束。
//详细见E盘api
gbc.weightx=1; gbc.weighty=1;
gbc.gridwidth=1; gbc.gridheight=1;
gbc.gridy=0;
gbc.gridx=4; panel.add(h[2],gbc);
gbc.gridx=6; panel.add(h[1],gbc);
gbc.gridy=1;
gbc.gridx=5; panel.add(zxjLable[1],gbc);
gbc.gridy=2;
gbc.gridx=0; panel.add(h[3],gbc);
gbc.gridx=3; panel.add(bambooLabel[1],gbc);
gbc.gridx=7; panel.add(bambooLabel[5],gbc);
gbc.gridx=10; panel.add(h[10],gbc);
gbc.gridy=3;
gbc.gridx=1; panel.add(zxjLable[2],gbc);
gbc.gridx=9; panel.add(zxjLable[5],gbc);
gbc.gridy=4;
gbc.gridx=0; panel.add(h[4],gbc);
gbc.gridx=10; panel.add(h[9],gbc);
gbc.gridy=5;
gbc.gridx=2; panel.add(bambooLabel[2],gbc);
gbc.gridx=8; panel.add(bambooLabel[4],gbc);
gbc.gridy=7;
gbc.gridx=2; panel.add(h[5],gbc);
gbc.gridx=3; panel.add(zxjLable[3],gbc);
gbc.gridx=7; panel.add(zxjLable[4],gbc);
gbc.gridx=8; panel.add(h[8],gbc);
gbc.gridy=8;
gbc.gridx=3; panel.add(h[6],gbc);
gbc.gridx=5; panel.add(bambooLabel[3],gbc);
gbc.gridx=7; panel.add(h[7],gbc);
ct.add(panel,BorderLayout.CENTER);
zxj[1]=new Zexuejia(1, zxjLable[1], bamboo[5], bambooLabel[5],
bamboo[1], bambooLabel[1], bambooImage[5], bambooImage[1], h[1], h[2]);
zxj[2]=new Zexuejia(2, zxjLable[2], bamboo[2], bambooLabe