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.