今天学习JAVA的多线程,看书看到一半,心血来潮,写了个程序,错误百出,不过也巩固了知识,程序如下:
//Sell.java import javax.swing.*; import java.awt.event.*; import java.awt.*;
public class Sell extends JFrame implements ActionListener { JTextArea taOut; JButton btnStart; JButton btnStop; JTextField jtf; Producethread produce; Customthread customer; Things thing; JPanel p1; JScrollPane p;
public Sell() { p1 = new JPanel(); taOut = new JTextArea(20,30); p1.add(taOut); p = new JScrollPane(p1); p.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); p.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); btnStart = new JButton("Start"); btnStart.addActionListener(this); btnStop = new JButton("Stop"); btnStop.addActionListener(this); jtf = new JTextField(6); getContentPane().add(p); getContentPane().add(jtf); getContentPane().add(btnStart); getContentPane().add(btnStop); getContentPane().setLayout(new FlowLayout()); thing = new Things(taOut); setTitle("Sell Test"); setBounds(100,0,370,460); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public void actionPerformed(ActionEvent ae) { if (ae.getActionCommand().equals("Start")) { produce = new Producethread(thing); customer = new Customthread(thing); customer.setSpeed(jtf.getText()); produce.start(); customer.start(); } if ( ae.getActionCommand().equals("Stop")) { produce.stop(); customer.stop(); } } public static void main(String[] args) { Sell se = new Sell(); } }
class Producethread extends Thread { Things th; public Producethread(Things thing) { th = thing; } public void run() { while(true) { th.addProduce(); try{ sleep(500); } catch(InterruptedException ie){ System.err.println("ERR:" + ie.toString()); } } } }
class Customthread extends Thread { Things th; int sh; public Customthread(Things thing) { th = thing; } public void run() { while(true) { th.sellProduce(); try{ sleep((int)(Math.random()*sh)); } catch(InterruptedException ie){ System.err.println("ERR:" + ie.toString()); } } } public void setSpeed(String s) { sh=Integer.parseInt(s)*2; } } class Things { JTextArea out; int total; private final static int MAX = 50; public Things(JTextArea taOut) { out=taOut; total=10; } public synchronized void addProduce() { try{ if (total<MAX) { total++; out.append("生产一产品加入仓库\n库存:"+ total + "\n"); }else{ out.append("满仓,暂停生产,等待中!\n"); wait(); } } catch(InterruptedException ie){ System.err.println("ERR:" + ie.toString()); } notify(); } public synchronized void sellProduce() { try{ if (total>0) { total--; out.append("出售一产品\n库存:"+ total + "\n"); }else{ out.append("缺货,等待生产中!\n"); wait(); } } catch(InterruptedException ie){ System.err.println("ERR:" + ie.toString()); } notify(); } }
程序能够正确运行,按正常方式操作是没有问题的,但当连续按两次或一上Start的时候,问题就来了,在actionPerformed方法中,处理Start是重新实例化两个线程对象并运行,但如果这两个对象原来就在运行中,就会使旧的两个对象变成不受控制,不能停止了,修改方法可以在重新实例化前增加调用stop()方法。或增加一个变量,判断两个对象是否在运行,是就不执行重新实例化。
在测试中,发现了stop()方法调用后,是不能用start()方法重新另其启动的。(书上没有明确写出) 。连续调用同一个线程对象两次start()方法将会出错,stop()方法不会. 
|