在Frame中有一线程,作用为不停的用随机数更新Frame中的文本域(JTextField),有一个按钮,我希望点击时停止该线程,我是这样写的:
//启动线程的按钮事件
if(e.getActionCommand().equals("shakeSelect"))
{

shakeThread = new ShakeThread();
shakeThread.start();

}//停止线程的按钮事件
//stop button
if(e.getActionCommand().equals("stopSelect"))
{

this.shakeThread.interrupt();
......
}
现在的问题是每次点击停止按钮,界面显示正常,但后台报错:Interrupted attempt to aquire write lock
怀疑是因为该线程不停的在更新JTextField,所以停止线程的时候可能正在做此操作
该怎么解决呢?

解决方案 »

  1.   

    最好的办法是,给this.shakeThread 设置一个变量。e.getActionCommand().equals("stopSelect"))
    {this.shakeThread.stopRunning=true;}
    在线程中进行判断 标记,比较妥当。
      

  2.   

    给你写个例子:import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.Random;public class Test extends Thread {
      private JFrame frame = new JFrame("线程暂停实验");
      private JTextField text = new JTextField(10);
      private JButton
          button_1 = new JButton("暂停"),
          button_2 = new JButton("开始");
      private boolean b = false; //哨兵
      /**
       * 构造实验窗体
       */
      public Test() {
        JPanel pane = new JPanel();
        frame.addWindowListener(new WindowAdapter(){
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        button_1.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent e) {
            stopThread();
          }
        });
        button_2.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent e) {
            startThread();
          }
        });
        Container con = frame.getContentPane();
        con.add(pane, BorderLayout.CENTER);
        pane.add(text);
        pane.add(button_1);
        pane.add(button_2);
        frame.setSize(300, 200);
        frame.setVisible(true);
      }
      /**
       * 暂停循环
       */
      public void stopThread() {
        b = true;
      }
      /**
       * 重新开始循环
       */
      public synchronized void startThread() {
        b = false;
        notify();
      }
      /**
       * run方法,线程的主体
       */
      public void run() {
    Random random = new Random();
        while (true) {
          try {
            sleep(100);
            synchronized (this) {
              while (b) { //如果哨兵为true
                wait();
              }
            }
          }
          catch (InterruptedException e) {}
          //将随机数写入TextField
          text.setText(String.valueOf(random.nextInt()));
        }
      }  public static void main(String[] args) {
        Test test = new Test();
        test.start();
      }
    }
      

  3.   

    to:mq612(五斗米)
    谢谢你的例子,对我帮助很大,但是我的Threak是作为我一个Panel的内部类,如果在主类中notify()我的内部类的线程的话,会报 “current thread not owner”错误
      

  4.   

    //线程的代码,内部类
    public class ShakeThread extends Thread
    {
    public synchronized void run()
    {
    int[] redNumber = new int[6];
    stopSelect.setEnabled(true);
    singleSelect.setEnabled(false);
    arraySelect.setEnabled(false);
    shakeSelect.setEnabled(false);
    clearSelect.setEnabled(false);
    saveSelect.setEnabled(false);
    while(true)
    {
    rdManger.getRedBallArray(redNumber,6);
    int blueNumber = rdManger.getOneBlueBall();
    for(int i=0;i<arrNumberField.length-1;i++)
    {
    arrNumberField[i].setText(String.valueOf(redNumber[i]));

    }
    arrNumberField[6].setText(String.valueOf(blueNumber));

    }

    }
    }//启动和暂停的代码
                      //shake Select
    if(e.getActionCommand().equals("shakeSelect"))
    {
    this.shakeThread.start();

    }
    //shake stop 
    if(e.getActionCommand().equals("stopSelect"))
    {

    this.shakeThread.interrupt();
    this.shakeSelect.setEnabled(true);
    this.arraySelect.setEnabled(true);
    this.singleSelect.setEnabled(true);
    this.clearSelect.setEnabled(true);
    this.saveSelect.setEnabled(true);
    this.stopSelect.setEnabled(false);

    }
      

  5.   

    你并没有用到线程的暂停功能,这样的话还不如每次开始都new一个新的线程出来,结束的时候用stop,如果不想在主类上继承Thread的话内部类也是个方法,你还可以使用接口,在给你个例子。
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.Random;
    //主类
    public class Test {
    private JFrame frame = new JFrame("线程暂停实验"); private JTextField text = new JTextField(10); private JButton button_1 = new JButton("暂停"), button_2 = new JButton("开始");

    private MyThread thread = new MyThread(text); // 自己的线程 /**
     * 构造实验窗体
     */
    public Test() {
    JPanel pane = new JPanel();
    frame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    button_1.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    thread.stopThread();
    }
    });
    button_2.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    thread.startThread();
    }
    });
    Container con = frame.getContentPane();
    con.add(pane, BorderLayout.CENTER);
    pane.add(text);
    pane.add(button_1);
    pane.add(button_2);
    frame.setSize(300, 200);
    frame.setVisible(true);
    thread.start();
    } public static void main(String[] args) {
    new Test();
    }
    }
    //内部类
    class MyThread extends Thread {
    private JTextField text = null; private boolean b = false; /**
     * 构造
     * @param text 传过来的JTextField
     */
    public MyThread(JTextField text) {
    this.text = text;
    } /**
     * 暂停循环
     */
    public void stopThread() {
    b = true;
    } /**
     * 重新开始循环
     */
    public synchronized void startThread() {
    b = false;
    notify();
    } /**
     * run方法,线程的主体
     */
    public void run() {
    Random random = new Random();
    while (true) {
    try {
    sleep(100);
    synchronized (this) {
    while (b) { // 如果哨兵为true
    wait();
    }
    }
    } catch (InterruptedException e) {
    }
    // 将随机数写入TextField
    text.setText(String.valueOf(random.nextInt()));
    }
    }}