在我看来,Object.wait 的超时版本很少按原样使用。这是因为:
- 该方法不处理虚假唤醒。
- 该方法不会指示它是由于通知还是超时而返回。
C++ version使用谓词作为参数似乎是正确的。 Object 中对应的带有签名的 Java 方法
boolean 等待(long timeOutMillis,BooleanSupplier条件)
可以方便地使用如下:
Object obj = ...;
BooleanSupplier condition = ...;
synchronized (obj) {
if (obj.wait(1000, condition)) {
// condition is fulfilled
} else {
// timeout happened
}
}
作为解决方法,我可以使用以下丑陋的辅助方法:
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;
}
}
}
我最好提出一些问题:
- 我说得对吗,它坏了?
- 他们为什么不解决这个问题?
- 有更好的方法来解决这个问题吗?
最佳答案
您的 safeWait(...)
原则上看起来不错,但您可以稍微简化一下:
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;
}
关于Java:Object.wait(long) 损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44575977/