等待(长超时)在一段时间循环?

2022-09-04 02:27:14

我已经读到你应该在一段时间内循环中将Java中的调用。原因是此线程可能被唤醒,并且您等待通知的条件仍然是假的(虚假唤醒)。Object.wait()

怎么样。在这里,您不希望循环使用条件,因为您希望它在指定的时间量后超时。但是,如果你不把它放在一个循环中,那么你怎么能确保它不会被提前唤醒呢?Object.wait(long timeout)


答案 1

但是,如果你不把它放在一个循环中,那么你怎么能确保它不会被提前唤醒呢?

这是Java IMO中的一个缺陷,尽管它可能是各种操作系统变体中底层线程支持的缺陷。我怀疑Java知道等待是否超时,但是调用方没有办法在不重新测试条件并专门测试时间的情况下弄清楚它。丑。

因此,您还需要将 放在一个循环中,并进行测试以查看时间是否超过超时期限。我不知道有其他方法可以做到这一点。wait(long timeout)while

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
}

答案 2
long deadline = now() + timeout;

synchronized(lock)

    while( !condition() && now()<deadline )
        lock.wait( deadline - now() );

    if(condition())
        ...
    else // timeout
        ...

推荐