Search code examples
javamultithreadingwaitinterruptspurious-wakeup

Is there a good way to distinguish spurious wake up and Thread.interrupt()?


I want to make a thread which can be interrupted at any time while be guarded against spurious wake ups. The problem here is that both spurious wakes as well as interrupts work the same: they throw InterruptedException

void anyMethodCalledByThread() {
  // .. a lot of work before
  while (wakingUpCondition) {
     try {
       lock.wait()
     } catch (InterruptedException e) {
       // is it spurious wake up and I should just ignore it?
       // or is it actual interrupt and I should do:
       // Thread.interrupt();
       // return;
       // and check interruption status in methods above to abort all tasks?
     }
  }
  // .. a lot of work after
}

From that I see, there is no way to distinguish them with just jdk, even Condition is of no use. Only possible solution I see is to use some extra volatile boolean per thread, but this makes Thread.interrupt() essentially useless by itself.


Solution

  • spurious wakes as well as interrupts work the same: they throw InterruptedException

    That's not my understanding. Spurious wakeups happen because a condition is awoken without being specifically signaled and has nothing to do with InterruptedException. Certain thread systems awaken all conditions when any condition is signaled due to implementation details. Spurious wakeups is one reason why we need a while loop by definition.

    If the wait() method throws InterruptedException then it was truly interrupted.

    // we use while loop because lock.wait() might return because of spurious wakeup
    while (wakingUpCondition) {
       try {
          lock.wait()
       } catch (InterruptedException ie) {
          // if the wait was interrupted then we should re-interrupt and maybe quit
          Thread.currentThread().interrupt();
          // handle the interrupt by maybe quitting the thread?
          return;
       }
    }
    

    As an aside, I contend that we use while loops less for spurious wakeup conditions (which are somewhat rare) and more for thread race conditions.