Reputation:
I have an issue trying to pause a threads execution from another thread. I have read the java docs and a few stack-overflow examples and still seem to be a little lost.
Many cases are just like mine; I have a gui that spawns a thread to do some work so it can stay responsive to the user. At some point the user does something that makes it desirable to just stop the worker thread before it executes its next statement. And then after sometime, continue its work.
I have read the wait
and notify
documentation for Threads
, and this seems to be the short answer to the question above(?).
And from what my IDE (netbeans) tells me, I must call wait
and notify
inside a synchronized block.
So here is what I had in my JFrame for when my start pause button was pressed. automator
is my Thread
object that I want paused. Its declared as static final
in my JFrame. firstRunDone
is just a flag for the first time the m_jbStartPause
is pressed, so the automator
can be started and not notified.
OnStartPauseButton()
{
synchronized(automator)
{
if(!running)
{
this.m_jbStartPause.setText("Pause");
running = true;
if(firstRunDone)
automator.notify();
else
automator.start();
firstRunDone = true;
}
else
{
this.m_jbStartPause.setText("Start");
running = false;
try { automator.wait(); } catch (InterruptedException ex) {}
}
}
}
My problem is with when I first try to pause the thread. I can hit start and the automator starts, but when I hit pause all that happens is the JFrame freezes and the automator continues doing its work.
Am i using syncronized wrong? Does automator
need any handling code?
Upvotes: 0
Views: 772
Reputation: 1130
FOllowing line is the issue
try { automator.wait(); } catch (InterruptedException ex) {}
This will cause the thread (YOUR GUI) thread to wait not the automator. JAVA docs says
wait()..Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed
That's why your JFrame appears to be frozen and automator keeps running. You need to build a mechanism in automator that polls the status of a flag to see if it needs to continue its work..and your GUI thread should change the status of the flag to stop automator from working. .
Upvotes: 1
Reputation: 12296
you'd better use SwingUtilities.invokeLater in order to update UI instead of using your worker thread
if you need to 'cancel' your thread, you need to make your "running" flag as volatile
instead of using "synchronized", I'd suggest to use ReentrantLock and it's conditions
Upvotes: 1