Reputation: 10331
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");
}
}
Upvotes: 2
Views: 515
Reputation: 11877
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"
Upvotes: 2