如何暂停所有正在运行的线程?然后恢复?

时间:2013-12-18 19:10:42

标签: java multithreading

我已经看过这个问题How pause and then resume a thread?

我在stackoverflow中看到了很多与我的问题相关的问题,但是我无法理解它们,因为它们是抽象的,而且不够具体到我的情境。

有2个倒计时标签。单击Start Button时,将执行倒计时。以同样的方式,当您点击Pause Button时,它应该暂停。但是,我收到错误:Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException

2线程已启动,但我无法使用wait()方法停止它。请让我知道如何停止线程,并实现resume按钮。谢谢。以下简单例子

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

class FirstCountDown extends SwingWorker<Integer, Integer> {

public Integer doInBackground() {
    for(int i=0; i<1000; i++){
    CountDown.count1.setText(String.valueOf(1000-i));
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    } 
    return null;
}
}

class SecondCountDown extends SwingWorker<Integer, Integer> {

public Integer doInBackground(){
    for(int i=0; i<1000; i++){
        CountDown.count2.setText(String.valueOf(1000-i));
    try {
        Thread.sleep(50);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }
    return null;
}
}

class CountDown extends JFrame  {

static JLabel count1;
static JLabel count2; 
static JButton startButton;
static JButton pauseButton;
static JButton resumeButton;
FirstCountDown first = new FirstCountDown();
SecondCountDown second = new SecondCountDown();

public CountDown(){
count1 = new JLabel("1000");
count2 = new JLabel("1000");
startButton = new JButton("start");
startButton.addActionListener(new ActionListener()  {
    public void actionPerformed(ActionEvent e){
        first.execute();
        second.execute();
    }
});
pauseButton = new JButton("pause");
pauseButton.addActionListener(new ActionListener()  {
    public void actionPerformed(ActionEvent e){
        try {
            first.wait();
            second.wait();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
});

resumeButton = new JButton("resume");

setSize(300,100);
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(count1);
add(count2);
add(startButton);
add(pauseButton);
add(resumeButton);
setVisible(true);

        }

public static void main(String args[]) {

    CountDown g = new CountDown();

}
}

1 个答案:

答案 0 :(得分:5)

您无法通过在其上调用wait()来暂停线程执行。 wait()暂停当前线程,直到另一个线程在前一个名为notify()的线程的同一对象上调用notifyAll()wait()。此外,为了在对象上调用wait()notify()notifyAll(),调用线程必须通过执行

来保存对象的监视器
synchronized(object) {
    object.wait();
}

为了暂停你的计数,你需要一个标志,并提供两种方法来暂停和恢复你的计数。类似的东西:

class FirstCountDown extends SwingWorker<Integer, Integer> {

    private _suspended = false;

    public synchronized void suspend() { _suspended = true; notify(); }
    public synchronized void resume() { _suspended = false; notify(); }

    public Integer doInBackground() {
        for(int i=0; i<1000; i++) {
            synchronized(this) {
                while (_suspended) {
                    wait(); // The current thread will block until some else calls notify()
                            // Then if _suspended is false, it keeps looping the for
                }
            }
            CountDown.count1.setText(String.valueOf(1000-i));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } 
        return null;
    }
}