Search code examples
javamultithreadingperformancethread-sleep

Best Method to pause a Thread?


I have a Runnable class which performs an operation continuously in its run method using an infinite while loop. Sometimes a user might want to pause/resume the operation. What is the best method to pause the Thread. I have two thoughts:

FIRST

class Foo extends Runnable {
    @Override
    public void run() {
    while(true) {
        if(pauseFlag)
           try{
              Thread.sleep();
           } catch(InterrruptedException ie) {//...}
    }
}

SECOND

class Foo extends Runnable {
    @Override
    public void run() {
        while(true) {
            //pause if user wants to pause
            while(pauseFlag);
        }
    }
}
  • In the FIRST case, when i use Thread.sleep inside loop the Netbeans IDE issues warning not to use Thread.sleep inside loop. Why is that?
  • In the SECOND case, when i use infinite empty while loop, is that a performance overhead?
  • Which method(mentioned above or otherwise) should i prefer to pause the action being performed by the Thread according to the users choice?

Because it has nothing to do with synchronization, i do not want to use wait/notify.


Solution

  • In the FIRST case, when i use Thread.sleep inside loop the Netbeans IDE issues warning not to use Thread.sleep inside loop. Why is that?

    I guess because Netbeans thinks that it won't be testing the loop condition and the code will pause unnecessarily.

    In the SECOND case, when i use infinite empty while loop, is that a performance overhead?

    Uh yes. Spinning a thread will take a CPU and be a performance sink.

    Which method(mentioned above or otherwise) should i prefer to pause the action being performed by the Thread according to the users choice?

    Neither? I would use a volatile boolean pauseFlag for testing if the thread should pause, combined with wait/notify to unpause it. Or you can use an AtomicBoolean which wraps a volatile boolean but is also an object we can synchronize on. Maybe something like:

    // using `AtomicBoolean` which wraps a `volatile boolean` but is const object
    // NOTE: we _can't_ synchronized on Boolean, needs to be constant object reference
    private final AtomicBoolean pauseFlag = new AtomicBoolean(false);
    ...
    while (!Thread.currentThread().isInterrupted()) {
        if (pauseFlag.get()) {
           synchronized (pauseFlag) {
              // we are in a while loop here to protect against spurious interrupts
              while (pauseFlag.get())) {
                 try {
                    pauseFlag.wait();
                 } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    // we should probably quit if we are interrupted?
                    return;
                 }
              }
           }
        }
        ...
    }
    ...
    public void pause() {
       pauseFlag.set(true);
    }
    ...
    public void resume() {
       pauseFlag.set(false);
       synchronized (pauseFlag) {
           pauseFlag.notify();
       }
    }
    

    I guess if I were forced to pick from one of the two, I would pick the sleep(...) loop. Even sleep(1) is significantly better than a spin. Do you really need to un-pause quicker than ~1ms? But the wait/notify is the most efficient.

    Because it has nothing to do with synchronization, i do not want to use wait/notify.

    As mentioned by @Jon, some sort of synchronization is necessary here since you are trying to communicate between two threads. Certainly you need to have memory synchronization otherwise any updates to pauseFlag will not be guaranteed to be shared between threads. This is handled by the volatile primitive on pauseFlag. By using wait/notify (which needs synchronized) your code can be much more efficient about the wakeup.