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();
}
}
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With