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.