Поведение future.get с 0 тайм-аутом - PullRequest
15 голосов
/ 17 февраля 2012

Может ли кто-нибудь указать мне какую-то документацию, в которой ясно, что «Future.get» с таймаутом 0 не будет ждать?

Документация 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();
   }

Ответы [ 2 ]

9 голосов
/ 17 февраля 2012

При необходимости ожидает самое большее заданное время…

Ожидание самое большее нулевых единиц времени вообще не ожидается.Это не явный намек, это явная гарантия.

7 голосов
/ 17 февраля 2012

Может кто-нибудь указать мне какую-то документацию, в которой ясно, что «Future.get» с таймаутом 0 не будет ждать?

Я могу указать вам код, если этопомогает.Глядя на 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 наносекунде.

...