未来行为.get with 0 timeout

2022-09-03 02:03:53

任何人都可以向我指出一些文档,这些文档清楚地表明超时值为0的“Future.get”不会等待?

的 API 文档未明确说明 的行为。独立存在,语句“如有必要,则最多等待给定时间......”这意味着这种调用根本不会等待,但考虑到(无限等待)的长期行为,我很紧张地依赖于“无等待”的行为java.util.concurrent.Futurefuture.get(0, unit)Object.wait(0)future.get(0, unit)

扫描某些 JDK 提供的类的源代码(即 )我看到这个特定的实现在超时值为0时不会等待。FutureTaskFuture

我想可以说

   long timeout = Math.max(until - now, 0);
   return future.get(timeout, TimeUnit.MILLISECONDS);

但是我对Future将其实现为无限等待感到紧张,所以相反,我已经按照我期望它工作的方式显式编码了它:

   long timeout = Math.max(until - now, 0);
   if(timeout > 0 || future.isDone()){
      return future.get(timeout, TimeUnit.MILLISECONDS);
   } else {
      throw TimeoutException();
   }

答案 1

如有必要,最多等待给定时间...

等待至多零时间单位根本不是等待。这不是一个隐含的暗示,而是一个明确的保证。


答案 2

任何人都可以向我指出一些文档,这些文档清楚地表明超时值为0的“Future.get”不会等待?

如果有帮助,我可以向你指出一些代码。查看然后继续,我看到以下循环,我已经将其缩减以显示相关位:java.util.concurrent.FutureTaskAbstractQueuedSynchronizer

private boolean doAcquireSharedNanos(int arg, long nanosTimeout) {
    long lastTime = System.nanoTime();
    for (;;) {
        ...
        if (nanosTimeout <= 0) {
            cancelAcquire(node);
            return false;
        }
        long now = System.nanoTime();
        nanosTimeout -= now - lastTime;
    }

这意味着如果是 0(如果你传入 0 来获得,它将是 0),那么它将尝试获取一次未来,然后超时并返回 false。nanosTimeout

如果它让你感觉更好,你可以将超时设置为1纳秒。