具有0超时的future.get的行为

mwh*_*den 15 java multithreading future

任何人都可以向我指出一些文档,明确表示超时为0的'Future.get`不会等待吗?

API文档for 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);
Run Code Online (Sandbox Code Playgroud)

但我很担心未来实现这是一个无限的等待,所以相反,我已经按照我希望它的工作方式明确编码:

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

eri*_*son 9

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

等待最多零时间单位并不等待.这不是一个隐含的暗示,它是一个明确的保证.

  • 理所当然的.我认为来自`Object.wait(long)`的语义差异将保证在文档中做出一些明确的区分.甚至`Object.wait`起初似乎也保证不会等待"超时" - 以毫秒为单位的最长等待时间"然后是后退并说"如果`超时'为零,那么实时性不会被考虑在内该线程只是等待通知." (3认同)

Gra*_*ray 7

任何人都可以向我指出一些文档,明确表示超时为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;
    }
Run Code Online (Sandbox Code Playgroud)

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

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