AFS AFS - 3 months ago 76
Java Question

wait(long timeout) in a while loop?

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?

Answer

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) {
    // we assume we are in a synchronized (object) here
    object.wait(timeoutExpiredMs - System.currentTimeMillis());
    // we might get improperly awoken here so we need to see if we timed out
    if (System.currentTimeMillis() >= timeoutExpiredMs) {
       // we timed out
       break;
    }
}
Comments