user1311286
user1311286

Reputation:

Java, using wait and notify properly to pause thread execution from another thread

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

Answers (2)

Amol Sonawane
Amol Sonawane

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

jdevelop
jdevelop

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

Related Questions