I've read that you're supposed to put Object.wait()
calls in Java in a while loop. The reason is that this thread may be woken up and the condition that you were waiting to notify on is still false (spurious wake-up).
What about Object.wait(long timeout)
. Here, you don't want to loop on the condition since you want it to time out after the specified amount of time. But if you don't put it in a loop then how can you ensure that it won't be woken up early?
But if you don't put it in a loop then how can you ensure that it won't be woken up early?
This is a deficiency in Java IMO although maybe it's a deficiency with the underlying thread support in various OS varients. I suspect Java knows whether the wait timed out or not but there is no way for the caller to figure it out without re-testing the condition and specifically testing the time. Ugly.
So you will need to put the wait(long timeout)
in a while
loop as well and also test to see if the time is past the timeout period. I know of no other way to accomplish this.
long timeoutExpiredMs = System.currentTimeMillis() + timeoutMs;
while (!condition) {
long waitMillis = timeoutExpiredMs - System.currentTimeMillis();
if (waitMillis <= 0) {
// timeout expired
break;
}
// we assume we are in a synchronized (object) here
object.wait(waitMillis);
// we might be improperly awoken here so we loop around to see if the
// condition is still true or if we timed out
}