2012-02-17 8 views
12

¿Alguien me puede indicar alguna documentación que deja en claro que un 'Future.get' con un tiempo de espera de 0 no esperará?Comportamiento de future.get con 0 tiempo de espera

Los documentos API para java.util.concurrent.Future no hacen explícito el comportamiento de future.get(0, unit). Parado por sí mismo, la afirmación "Espera si es necesario para, como máximo, el tiempo dado ..." implica que esta invocación no esperará en absoluto, pero dado el comportamiento de larga data de Object.wait(0) (espera infinita), estoy nervioso de depender en un comportamiento "no esperar" de future.get(0, unit)

el escaneo de la fuente de algunas clases de JDK-proporcionado (a saber. FutureTask) Veo que esta implementación particular de Future no espera cuando el tiempo de espera es 0.

I' me gustaría poder decir

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

pero estoy nervioso por un Futuro implementación que a medida que una espera infinita, así que en vez, he codificado explícitamente la forma en que se puede esperar que funcione:

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

@skaffman Gracias por la reparación de la etiqueta. – mwhidden

Respuesta

7

Espera si es necesario como máximo en el tiempo dado & hellip;

Esperando en la mayoría de cero unidades de tiempo no espera a todos. Esa no es una pista implícita, es una garantía explícita.

+3

concedido. Pensé que esta diferencia en la semántica de 'Object.wait (long)' habría justificado alguna distinción explícita hecha en los documentos. Incluso 'Object.wait' al principio parece garantizar que no hay espera" 'timeout' - el tiempo máximo de espera en milisegundos" pero luego retrocede y dice "Si' timeout' es cero, sin embargo, el tiempo real no se toma en consideración y el hilo simplemente espera hasta que se lo notifiquen ". – mwhidden

5

Te puedo apuntar a un cierto código si eso ayuda. Mirando hacia java.util.concurrent.FutureTask y luego a AbstractQueuedSynchronizer veo el siguiente bucle que he recortado para mostrar los bits relavent:

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

Esto significa que si nanosTimeout es 0 (que lo será si se pasa en 0 a get) luego intentará adquirir el futuro una vez y luego expirará y devolverá false.

Si te hace sentir mejor, puedes configurar el tiempo de espera en 1 nanosegundo.

+0

Gracias! Ese es exactamente el código que revisé durante mi propia investigación. – mwhidden