@Lxjeng
2016-05-13T10:00:08.000000Z
字数 5522
阅读 881
- 报告提交日期:2016.5.13 报告提交截止日期:2016.5.13
- 姓名:梁晓静 学号:1405010530 班级:计算机5班
- 生产消费者问题
- 参考理发师问题,重新做一个具有GUI界面演示的生产者消费者问题的小软件,可用Java/QT相关编程来解决界面设计与实现问题!
- java编译平台eclipse
- 做一个具有GUI界面演示的生产者消费者问题的小软件。
- 生产者和消费者线程通过Synchronized互斥锁对Stack共享资源进行访问,加了synchronized锁后,才能调用wait(),notify()和notifyAll()操作。生产者生产了一个apple“#"后调用push将apple“#”放到Stack中,如果Stack已满,生产者线程wait(),同时解锁,放开占有的资源,消费者对Stack操作,否则唤醒生产者并将apple“#”入栈;消费者也是同样的。本实验10个生产者,5个消费者。


package lxjeng;import java.awt.*;import java.awt.event.*;import javax.swing.*;public class PC extends WindowAdapter {// 主程序public PC() {JFrame f = new JFrame("生产者消费者图形界面模拟");JMenuBar menuBar = new JMenuBar();Content content = new Content();f.add("Center", content);Control control = new Control(content);f.add("North", control);f.setVisible(true);f.setSize(600, 570);Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();Dimension frameSize = f.getSize();f.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);// 设置主界面显示位置f.addWindowListener(this);f.setJMenuBar(menuBar);/* menuHelp.add(menuHelpAbout);menuBar.add(menuHelp);*/}void fileExit_ActionPerformed(ActionEvent e) {System.exit(0);}public void windowClosing(WindowEvent arg0) {System.exit(0);}public static void main(String args[]) {new PC();}}class Content extends JPanel {// content是主显示部分JTextField tf1, tf2, tf3, tf4, tf5, tf6;JTextArea ta;public Content() {setLayout(null);tf1 = new JTextField();// 六个JTextField模仿堆栈tf2 = new JTextField();tf3 = new JTextField();tf4 = new JTextField();tf5 = new JTextField();tf6 = new JTextField();add(tf1);add(tf2);add(tf3);add(tf4);add(tf5);add(tf6);int a = 94;int b = 100;int c = 197, d = 45;tf1.setBounds(new Rectangle(b, a + 225, c, d));// JTextField的显示位置tf2.setBounds(new Rectangle(b, a + 180, c, d));tf3.setBounds(new Rectangle(b, a + 135, c, d));tf4.setBounds(new Rectangle(b, a + 90, c, d));tf5.setBounds(new Rectangle(b, a + 45, c, d));tf6.setBounds(new Rectangle(b, a, c, d));tf1.setHorizontalAlignment(JTextField.CENTER); // JTextField中的内容居中显示tf2.setHorizontalAlignment(JTextField.CENTER);tf3.setHorizontalAlignment(JTextField.CENTER);tf4.setHorizontalAlignment(JTextField.CENTER);tf5.setHorizontalAlignment(JTextField.CENTER);tf6.setHorizontalAlignment(JTextField.CENTER);ta = new JTextArea();JScrollPane sp = new JScrollPane(ta);add(sp);sp.setBounds(new Rectangle(380, 50, 170, 370));ta.setLineWrap(true);}int z = 0;public void showPush(char c, int index) {// 入栈的界面显示控制switch (index) {case 1:tf1.setText("" + c + "");break;case 2:tf2.setText("" + c + "");break;case 3:tf3.setText("" + c + "");break;case 4:tf4.setText("" + c + "");break;case 5:tf5.setText("" + c + "");break;case 6:tf6.setText("" + c + "");}ta.insert(Thread.currentThread().getName() + "生产:" + "apple" + c + "\n", z);}public void showPop(char c, int index) {// 出栈的界面显示控制switch (index) {case 1:tf1.setText("");break;case 2:tf2.setText("");break;case 3:tf3.setText("");break;case 4:tf4.setText("");break;case 5:tf5.setText("");break;case 6:tf6.setText("");}ta.insert(Thread.currentThread().getName() + "消费:" + "apple" + c + "\n", z);}public void clear() {// 清空JTextArea来进行“重新开始”ta.setText("");}public void full() {ta.insert("栈满,生产者wait\n", z);}public void empty() {ta.insert("栈空,消费者wait\n", z);}}class Control extends JPanel implements ActionListener {JButton start = new JButton("开始");Content content;public Control(Content content) {this.content = content;add(start);start.addActionListener(this);}public void actionPerformed(ActionEvent e) {go();}public void go() {SyncStack stack = new SyncStack(content);Runnable producer1 = new Producer(stack);Runnable producer2 = new Producer(stack);Runnable producer3 = new Producer(stack);Runnable producer4 = new Producer(stack);Runnable consumer1 = new Consumer(stack);Runnable consumer2 = new Consumer(stack);Runnable consumer3 = new Consumer(stack);Runnable consumer4 = new Consumer(stack);Thread p1 = new Thread(producer1, "生产者1");Thread p2 = new Thread(producer2, "生产者2");Thread p3 = new Thread(producer3, "生产者3");Thread p4 = new Thread(producer4, "生产者4");Thread p5 = new Thread(producer4, "生产者5");Thread p6 = new Thread(producer4, "生产者6");Thread p7 = new Thread(producer4, "生产者7");Thread p8 = new Thread(producer4, "生产者8");Thread p9 = new Thread(producer4, "生产者9");Thread p10 = new Thread(producer4, "生产者10");Thread c1 = new Thread(consumer1, "消费者1");Thread c2 = new Thread(consumer2, "消费者2");Thread c3 = new Thread(consumer2, "消费者3");Thread c4 = new Thread(consumer2, "消费者4");Thread c5 = new Thread(consumer2, "消费者5");p1.start();p2.start();p3.start();p4.start();p5.start();p6.start();p7.start();p8.start();p9.start();p10.start();c1.start();c2.start();c3.start();c4.start();c5.start();}}class SyncStack// 共享资源{Content theCon;public SyncStack(Content c) {theCon = c;}private int index = 0;// 堆栈指针初始值为0private char[] buffer = new char[6];// 堆栈有6个字符的空间public synchronized void push(char c)// 加上互斥锁{while (index == buffer.length)// 堆栈已满,不能压栈{try {this.wait();// 等待,直到有数据出栈theCon.full();} catch (InterruptedException e) {}}this.notify();buffer[index] = c;index++;theCon.showPush(c, index);}public synchronized char pop(){while (index == 0){try {this.wait();theCon.empty();} catch (InterruptedException e) {}}this.notify();char c = buffer[index - 1];theCon.showPop(c, index);index--;return buffer[index];}}class Producer implements Runnable{SyncStack theStack;public Producer(SyncStack s) {theStack = s;}public void run() {char c;for (int i = 0; i < 20; i++) {c = '#';theStack.push(c);try {Thread.sleep((int) (Math.random() * 4000));// 每产生一个字母后线程就随即睡眠一段时间} catch (InterruptedException e) {}}}}class Consumer implements Runnable{SyncStack theStack;public Consumer(SyncStack s) {theStack = s;}public void run() {char c;for (int i = 0; i < 20; i++) {c = theStack.pop();try {Thread.sleep((int) (Math.random() * 6000));} catch (InterruptedException e) {}}}}
- 本次实验对我来说有一定难度,在参考老师给的理发师问题相关资料和同学做好的实验后,理解了他程序的大概意思,然而自己还是不能独立完成,所以借鉴了其源程序加以理解和稍稍修改。这次实验的关键在于同步方法和锁的机制,也让我见识到了Java对多线程的支持与同步机制的强大。