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.
CodePudding user response:
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.