2011-11-18 16 views
6

Aquí hay un caso en el que un subproceso está esperando notificación() o un tiempo de espera excedido. Aquí se agrega un ciclo while para manejar el despertar espurio.Java: cómo distinguir entre el despertar espúreo y el tiempo de espera en espera()

boolean dosleep = true; 
while (dosleep){ 
    try { 
     wait(2000); 
     /** 
     * Write some code here so that 
     * if it is spurious wakeup, go back and sleep. 
     * or if it is timeout, get out of the loop. 
     */ 

    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

En este caso, ¿cómo puedo distinguir entre un despertar espurio y un tiempo de espera? Si se trata de un despertar espurio, necesito volver y esperar. Y si es un tiempo de espera, necesito salirme del lazo.

Puedo identificar fácilmente el caso de notify(), porque estableceré la variable dosleep en falso mientras notifica() la llamada.

EDITAR: estoy usando la versión 1.4 de Java, debido a los requisitos del proyecto incorporado. No puedo usar Condition ya que está disponible solo después de 1.5.

Gracias de antemano.

+0

Bringer128 tiene una solución razonable, pero, me pregunto por qué quieres hacer esto. La interrupción generalmente no es una "activación espuria", es una señal para interrumpir y detener el proceso. – user949300

+0

No se trata de interrupción. Una "activación espuria" puede venir en cualquier momento. Si se produce al mismo tiempo después de ingresar a la espera(), entonces no quiero salir del ciclo. Necesito asegurarme de que aguardo el tiempo de 'expiración' antes de salir del ciclo –

+0

que veo. No te interrumpirán, pero otro hilo está llamando a notify() o, más probablemente, notifyAll(), y te despiertan. – user949300

Respuesta

4

Debe hacer un seguimiento de su tiempo de espera si desea distinguir los dos casos.

long timeout = 2000; 
long timeoutExpires = System.currentTimeMillis() + timeout; 
while(dosleep) { 
    wait(timeout); 
    if(System.currentTimeMillis() >= timeoutExpires) { 
    // Get out of loop 
    break; 
    } 
} 

Dicho esto, la recomendación de utilizar la clase Condition de Denis es la mejor manera de hacer esto.

+0

Este código espera nuevamente durante todo el tiempo de espera después de que se haya producido la activación falsa y que no sea correcto. La respuesta de Cameron Skinner es correcta y también es compatible con JDK v4 (mientras que la respuesta de Denis.Solonenko también es correcta, utiliza la API 'java.concurrency' y, por lo tanto, necesita JDK v5 +). Esa es mi parte del tema. –

+2

No use System.currentTimeMillis() use alguna forma de tiempo monotónico en su lugar ya que esto es propenso a portarse mal cuando se cambia el reloj del sistema. http://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime –

+0

Como ha señalado Jiri Patera, el ejemplo es defectuoso en sí mismo. Además, además de la "clase de condición" que realmente es una interfaz, el JavaDoc de [Condition] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html) dice claramente que 'Una implementación es libre de eliminar la posibilidad de activaciones espúreas, pero se recomienda que los programadores de aplicaciones siempre asuman que pueden ocurrir y, por lo tanto, siempre esperan en un bucle '. Cameron Skinner tiene la única respuesta correcta. –

4

Creo que Lock sy Condition se adaptarán mejor a sus necesidades en este caso. Verifique los javadocs para Condition.awaitUntil() - tiene un ejemplo de uso

+1

estoy usando la versión 1.4 java, debido al requisito de proyecto integrado. Me temo que Condition está disponible solo después de 1.5. –

6

Usted puede hacer esto:

boolean dosleep = true; 
long endTime = System.currentTimeMillis() + 2000; 
while (dosleep) { 
    try { 
     long sleepTime = endTime - System.currentTimeMillis(); 
     if (sleepTime <= 0) { 
      dosleep = false; 
      } else { 
      wait(sleepTime); 
     } 
    } catch ... 
} 

Eso debería funcionar bien en Java 1.4, y se asegurará de que el hilo tiene capacidad para al menos 2000 ms.

Cuestiones relacionadas