java模拟哲学家就餐问题

废话不多说 直接上代码

1.筷子类 他有两个属性, 一个是标示这根筷子在哪个哲学家手边,另一个属性标示这个筷子的状态,并且这个状态是随时从内存当中取出的

package com.bjs.dinning;

public class Chopstick {
	/**
	 * 表示筷子是否可用
	 * */
	private volatile boolean available = true;

	private int id;

	public Chopstick() {

	}

	public Chopstick(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public boolean isAvailable() {
		return available;
	}

	public void setAvailable(boolean available) {
		this.available = available;
	}

	public void setId(int id) {
		this.id = id;
	}
	@Override
	public String toString() {
		return "筷子" + id;
	}
}

2.筷子数组  动态决定几个哲学家 几根筷子

package com.bjs.dinning;

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

	public Chopstick getLast(int id) {
		if (id == 0) {
			return chopsticks[chopsticks.length - 1];
		} else {
			return chopsticks[id - 1];
		}
	}
}

3.哲学家类

package com.bjs.dinning;

import java.util.Random;

import javax.swing.JTextArea;

public class Philosopher implements Runnable {

	ChopstickArray chopstickArray;

	JTextArea eatingTextArea;

	private int id;

	private boolean state;

	JTextArea thinkingTextArea;

	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 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();
		}
	}
	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;
	}
	@Override
	public String toString() {
		return " 哲学家 " + id;
	}

}

4.运行的入口类 

package com.bjs.dinning;

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(3);
                for(int i = 0; i < 3; 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("开始运行");
}


转载于:https://my.oschina.net/u/1455908/blog/203183

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值