Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pause all running threads? and then resume?

I have already seen this question : How pause and then resume a thread?

I have seen many questions in stackoverflow related to my issue, but I couldn't understand them because they are abstract and not specific enough to my sitiuation.

There are 2 Count Down Labels. When you click Start Button, the countdown is executed. In the same way, when you click Pause Button, it should be paused. However, I am getting an error: Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException

2 Threads are started, but I can't stop it with the wait() method. Please let me know how can I stop threads, and implement resume button. Thanks. Easy Example below

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();

}
}
like image 283
ton1 Avatar asked Dec 18 '13 19:12

ton1


1 Answers

You can't suspend a thread execution by invoking wait() on it. wait() suspend the current thread until another thread calls notify() or notifyAll() on the same object the previous thread called wait() on. Moreover, in order to call wait(), notify() or notifyAll() on an object, the calling thread must hold that object's monitor by doing

synchronized(object) {
    object.wait();
}

In order to suspend your counting, you need a flag and provide two methods to suspend and resume your counting. Something like:

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;
    }
}
like image 194
Raffaele Rossi Avatar answered Sep 21 '22 15:09

Raffaele Rossi