2010-09-26 25 views
12

Tengo un escenario en el que quiero que un hilo duerma durante un tiempo específico.¿Cómo hacer que un hilo duerma durante un tiempo específico en Java?

Código:

public void run(){ 
     try{ 
      //do something 
        Thread.sleep(3000); 
//do something after waking up 
       }catch(InterruptedException e){ 
       // interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds? 
       } 
     } 

Ahora ¿Cómo manejo el caso en el que el hilo que estoy tratando de correr es golpeado con una excepción interrumpido antes de que el total del sueño? También, ¿se despierta el subproceso después de ser interrumpido y pasa a estado ejecutable o cuando solo después de pasar a ejecutable el flujo pasa al bloque catch?

Respuesta

1
  1. usando Sueño en mi experiencia suele ser para compensar el mal momento en algún otro lugar en el programa, ¡reconsidere!
  2. probar esto:

    public void run(){ 
         try{ 
          //do something 
          long before = System.currentTimeMillis(); 
          Thread.sleep(3000); 
          //do something after waking up 
         }catch(InterruptedException e){ 
          long diff = System.currentTimeMillis()-before; 
          //this is approximation! exception handlers take time too.... 
          if(diff < 3000) 
           //do something else, maybe go back to sleep. 
           // interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds? 
         } 
    } 
    
  3. si no se interrumpe el sueño mismo, ¿por qué se despertó este hilo? es decir que parece que está haciendo algo muy malo ...

+0

La interrupción puede provenir de un evento externo, como una solicitud de 'cierre gracioso' del sistema operativo. –

+0

@Tony: es el mismo principio. la interrupción aún indica una solicitud deliberada para cancelar el hilo, no es algún tipo de evento casual que el hilo sea "golpeado", como parece indicar la fraseología del OP. –

1

Según this page vas a tener que codificarlo a comportarse de la manera que desee. Al utilizar el hilo que se encuentra arriba, se interrumpirá su suspensión y su hilo se cerrará. Idealmente, volvería a lanzar la excepción para que cualquier cosa que inicie el hilo pueda tomar la acción adecuada.

Si no desea que esto suceda, puede poner todo en un ciclo while (verdadero). Ahora, cuando ocurre la interrupción, se interrumpe el sueño, se come la excepción y se activa para comenzar un nuevo sueño.

Si desea completar los 3 segundos de sueño, puede aproximarlo teniendo, digamos, 10 duerme de 300 milisegundos, y manteniendo el contador de bucle fuera de un bucle while. Cuando vea la interrupción, cómala, coloque una bandera de "Tengo que morir" y continúe dando vueltas hasta que haya dormido lo suficiente. Luego, interrumpes el hilo de forma controlada.

Aquí hay una manera:

public class ThreadThing implements Runnable { 
    public void run() { 
     boolean sawException = false; 
     for (int i = 0; i < 10; i++) { 
      try { 
       //do something 
       Thread.sleep(300); 
       //do something after waking up 
      } catch (InterruptedException e) { 
       // We lose some up to 300 ms of sleep each time this 
       // happens... This can be tuned by making more iterations 
       // of lesser duration. Or adding 150 ms back to a 'sleep 
       // pool' etc. There are many ways to approximate 3 seconds. 
       sawException = true; 
      } 
     } 
     if (sawException) Thread.currentThread().interrupt(); 
    } 
} 
1

¿Por qué quiere dormir durante exactamente 3 segundos? Si solo tiene que ejecutar algo después de un tiempo, intente con un Timer.

+0

El temporizador sería mejor, pero introduce el potencial de problemas de competencia y concurrencia que podrían evitarse simplemente durmiendo. Sin embargo, creo que valdría la pena la curva de aprendizaje para usar temporizadores. – locka

+0

el enlace del temporizador anterior parece estar roto – AkD

10

Cuando su hilo es golpeado por una interrupción irá al bloque catch InterruptedException. Luego puede verificar cuánto tiempo ha estado durmiendo el hilo y calcular cuánto más tiempo queda para dormir. Finalmente, en lugar de tragar la excepción, es una buena práctica restaurar el estado de interrupción para que el código más arriba en la pila de llamadas pueda manejarlo.

public void run(){ 

    //do something 

    //sleep for 3000ms (approx)  
    long timeToSleep = 3000; 
    long start, end, slept; 
    boolean interrupted; 

    while(timeToSleep > 0){ 
     start=System.currentTimeMillis(); 
     try{ 
      Thread.sleep(timeToSleep); 
      break; 
     } 
     catch(InterruptedException e){ 

      //work out how much more time to sleep for 
      end=System.currentTimeMillis(); 
      slept=end-start; 
      timeToSleep-=slept; 
      interrupted=true 
     } 
    } 

    if(interrupted){ 
     //restore interruption before exit 
     Thread.currentThread().interrupt(); 
    } 
} 
1

que usarlo de esta manera:

lo que no es necesario esperar el tiempo específico para terminar.

public void run(){ 

    try { 

     //do something 

     try{Thread.sleep(3000);}catch(Exception e){} 

     //do something 

    }catch(Exception e){} 

} 
Cuestiones relacionadas