如何区分等待(长时间超时)退出通知或超时?

具有此等待声明:

public final native void wait(long timeout) throws InterruptedException;

它可能通过DisruptedException或超时退出,或者因为在另一个线程中调用了 Notify/NotifyAll方法,Exception很容易捕获,但是...

有没有办法知道退出原因是否超时或通知?

编辑:

这是一种棘手的工作方式,(尽管我不喜欢它)

          long tBefore=System.currentTimeMillis();
          wait(TIMEOUT);
          if ((System.currentTimeMillis() - tBefore) > TIMEOUT) 
            { 
               //timeout
            }

答案 1

通知可以返回的另一个原因:虚假唤醒。这是一件不太可能但可能的事情,因为在某些硬件/操作系统组合上,防止虚假唤醒是非常昂贵的。

因此,您始终必须在循环中调用wait()并重新检查您正在等待的条件。在这项工作中,很容易同时检查超时。

有关详细信息,我推荐“Java 并发实践”一书。使用更高级别的构造,这将使这一切对你来说是正确的。


答案 2

这并不能完全回答问题,但它可能会解决您的问题:使用更高级别的并发机制。等待/通知通常比您想要的更低级别,原因有很多。

例如,如果您使用的是 BlockingQueue.poll(long, TimeUnit),则可以检查结果是否为 null,以了解是否超时。