This bug was found by a Chinese java community long time age:
http://mislay.javaeye.com/blog/348338. I think it's best to fix like this:
private boolean await0(long timeoutMillis, boolean interruptable) throws
InterruptedException {
long startTime = System.currentTimeMillis();
//long endTime = System.currentTimeMillis() + timeoutMillis;
synchronized (lock) {
if (ready) {
return ready;
} else if (timeoutMillis <= 0) {
return ready;
}
waiters++;
try {
for (;;) {
try {
long timeOut = Math.min(timeoutMillis,
DEAD_LOCK_CHECK_INTERVAL);
lock.wait(timeOut);
} catch (InterruptedException e) {
if (interruptable) {
throw e;
}
}
if (ready) {
return true;
} else {
//if (endTime < System.currentTimeMillis()) {
if (System.currentTimeMillis() - startTime >
timeoutMillis) {
return ready;
}
}
}
} finally {
waiters--;
if (!ready) {
checkDeadLock();
}
}
}
}
The difference between two time values will never be overflowed!