Question

Can anyone point me to some documentation that makes clear that a 'Future.get` with a timeout of 0 will not wait?

The API docs for java.util.concurrent.Future does not make explicit the behavior of future.get(0, unit). Standing on its own, the statement "Waits if necessary for at most the given time..." implies this invocation will not wait at all, but given the long-standing behavior of Object.wait(0) (infinite wait), I'm nervous to depend on a "no wait" behavior of future.get(0, unit)

Scanning the source of some JDK-provided classes (viz. FutureTask) I see that this particular implementation of Future does not wait when the timeout is 0.

I'd like to be able to say

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

but I'm nervous about a Future implementing that as an infinite wait, so instead, I've explicitly coded it the way I would expect it to work:

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

Solution

Waits if necessary for at most the given time…

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

OTHER TIPS

Can anyone point me to some documentation that makes clear that a 'Future.get` with a timeout of 0 will not wait?

I can point you at some code if that helps. Looking into java.util.concurrent.FutureTask and then on to AbstractQueuedSynchronizer I see the following loop which I've pared down to show the relavent bits:

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

This means that if nanosTimeout is 0 (which it will be if you pass in 0 to get) then it will try to acquire the future once and then timeout and return false.

If it makes you feel any better, you can set your timeout to be 1 nanosecond.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top