It seems to me as if the timeout version of Object.wait is rarely usable as-is. This is because:
The C++ version with the predicate as parameter seems to make it right. A corresponding Java method in Object with signature
boolean wait(long timeOutMillis, BooleanSupplier condition)
could be used conveniently as follows:
Object obj = ...;
BooleanSupplier condition = ...;
synchronized (obj) {
if (obj.wait(1000, condition)) {
// condition is fulfilled
} else {
// timeout happened
}
}
As a workaround, I could use the following ugly helper method:
public static boolean safeWait(Object waitObject, long timeOutMillis, BooleanSupplier condition) throws InterruptedException {
if (condition.getAsBoolean()) {
return true;
}
long rest = timeOutMillis;
while (true) {
long t0 = System.currentTimeMillis();
waitObject.wait(rest);
long t1 = System.currentTimeMillis();
long waited = t1 - t0;
if (condition.getAsBoolean()) {
return true;
}
rest = rest - waited;
if (rest <= 0) {
return false;
}
}
}
I better should formulate some questions:
Your safeWait(...)
looks good in principle, but you could streamline it a bit:
public static boolean safeWait(Object waitObject, long timeOutMillis, BooleanSupplier condition)
throws InterruptedException
{
long now = System.currentTimeMillis();
long end_time = now + timeOutMillis;
while (! condition.getAsBoolean()) {
if (now > end_time) {
return false;
}
waitObject.wait(end_time - now);
now = System.currentTimeMillis();
}
return true;
}