Question

I know that if I call Object.wait() I have to account for spurious wakeups so I should wrap the wait in a while loop that checks if my actual terminating condition was reached. But in cases where I use java.util.concurrent.* classes should I still worry about that?

I am using a java.util.concurrent.BlockingQueue and I want to know if when I do queue.take() I should expect that sometimes take() will stop blocking because of a spurious wakeup (InterruptedException) and not because it actually read something from the queue. In other words, if spurious wakeups are a risk, I need to catch the InterruptedException INSIDE a while loop that actually checks for termination. If they are not, then I should probably leave InterruptedExceptions break the main-loop and stop processing when I get one

Or in code

@Override
public void run() {
  while(running()) {
    try {
       queue.take();
    } catch (InterruptedException exc) {
       log.warn("Spurious wakeup, ignore and try again");
    }
  }
}

vs

@Override
public void run() {
  try {
    while(running()) {
       queue.take();
    }
  } catch (InterruptedException exc) {
      log.error("Some other reason for InterruptedException, finish thread");
  }
}
Était-ce utile?

La solution

Going off of this question: Can Semaphore.acquire() throw InterruptedException due to a spurious wakeup?

It appears that a spurious wakeup does not actually interrupt the thread, so it seems that you don't need to have the try/catch there (edit: for a spurious wakeup, that is. You still need to have it in case the waiting thread is actually interrupted).

According to the first answer there:

"It is "spurious wakeup" not "spurious interrupt": "A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup." There is no InterruptedException thrown during a spurious wakeup. As you say in the comments: The thread wakes up but the interrupted flag is not set"

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top