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

时间:2012-02-17 17:41:01

标签: java multithreading future

有人能指出我的一些文件,明确表示超时为0的'Future.get`不会等待吗?

java.util.concurrent.Future的API文档未明确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);

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

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

2 个答案:

答案 0 :(得分:9)

  

最多在给定时间内等待......

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

答案 1 :(得分: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;
    }

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

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