wait(long timeout) in a while loop?

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
}

long deadline = now() + timeout;

synchronized(lock)

    while( !condition() && now()<deadline )
        lock.wait( deadline - now() );

    if(condition())
        ...
    else // timeout
        ...

it is because java has Mesa style monitors instead of Hoare style monitors. So you need to put wait in a while loop. Please search the string "For this reason, it is usually necessary to enclose each wait operation in a loop like this" on the follwing web page,

http://en.wikipedia.org/wiki/Monitor_(synchronization)#Nonblocking_condition_variables

.if it had been a Hoare style monitors then you could have put your wait in if. I will soon add details of Mesa monitors. This is not deficiency in Java. Both types of monitors have advantages and disadvantages.