17

任何人都可以向我指出一些明确说明超时为 0 的“Future.get”不会等待的文档吗?

API 文档java.util.concurrent.Future没有明确说明future.get(0, unit). 就其本身而言,声明“如果需要,最多等待给定时间......”意味着这个调用根本不会等待,但考虑到(无限等待)的长期行为Object.wait(0),我很紧张依赖的“不等待”行为future.get(0, unit)

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

我想能够说

   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();
   }
4

2 回答 2

10

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

Waiting for at most zero time units is not waiting at all. That's not an implicit hint, it's an explicit guarantee.

于 2012-02-17T17:46:55.617 回答
8

任何人都可以向我指出一些明确说明超时为 0 的“Future.get”不会等待的文档吗?

如果有帮助,我可以为您指出一些代码。查看java.util.concurrent.FutureTask然后再查看AbstractQueuedSynchronizer我看到以下循环,我已将其缩减以显示相关位:

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;
    }

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

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

于 2012-02-17T17:46:35.947 回答