80

¿Cuándo lanza Thread.sleep de Java la excepción InterruptedException? ¿Es seguro ignorarlo? No estoy haciendo multihilo. Solo quiero esperar unos segundos antes de volver a intentar alguna operación.¿Cuándo lanza Thread.sleep de Java la excepción InterruptedException?

+2

http://stackoverflow.com/questions/1024651/do-i-have-to-worry-about-interruptedexceptions-if-i-dont-interrupt-anything-myse –

+1

Depende en qué sentido se refiere a "ignorar" . 'InterruptedException' es una excepción detectada, por lo que no puede compilar a menos que maneje o declare este tipo de excepción en cualquier método que una o que duerma un' Thread', o que llame 'wait()' en 'Object'. – 8bitjunkie

+1

Este artículo puede ayudarlo a comprender este mecanismo: [¿Qué hace con InterruptedException?] (Http://www.yegor256.com/2015/10/20/interrupted-exception.html) – yegor256

Respuesta

24

Por lo general, NO debe ignorar la excepción. Echar un vistazo al siguiente documento:

No ingerir interrupciones

veces lanzando InterruptedException se no es una opción, por ejemplo, cuando una tarea definida por Ejecutable llama a un método interrumpible . En este caso, no puede volver a lanzar InterruptedException, pero tampoco desea hacer nada. Cuando un método de bloqueo detecta la interrupción y lanza InterruptedException, , borra el estado interrumpido. Si detecta InterruptedException pero no puede volver a lanzarla, debe conservar la evidencia de que se produjo la interrupción para que el código más arriba en la pila de llamadas pueda saber de la interrupción y responder si así lo desea. Esta tarea se realiza llamando a interrupt() para "reinterrumpir" el subproceso actual , como se muestra en el Listado 3. Como mínimo, siempre que detecte InterruptedException y no lo vuelva a generar, vuelva a interrumpir el subproceso actual antes de devolver.

public class TaskRunner implements Runnable { 
    private BlockingQueue<Task> queue; 

    public TaskRunner(BlockingQueue<Task> queue) { 
     this.queue = queue; 
    } 

    public void run() { 
     try { 
      while (true) { 
       Task task = queue.take(10, TimeUnit.SECONDS); 
       task.execute(); 
      } 
     } 
     catch (InterruptedException e) { 
      // Restore the interrupted status 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

Ver el documento completo aquí:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

+0

no se encuentra la página. ¿Podrías actualizar tu publicación? – Laurence

+1

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs- –

4

una manera sólida y fácil de manejar en el código de un solo subproceso haría segundo e atraparlo y retrotraerlo en una RuntimeException, para evitar la necesidad de declararlo para cada método.

9

El boletín de Java Specialists (que puedo recomendar sin reservas) tenía un interesting article on this, y cómo manejar el InterruptedException. Vale la pena leer y digerir.

-4

El InterruptedException generalmente se arroja cuando se interrumpe el sueño.

+11

Eso está mal, ya que no es el propio sueño el que se interrumpe, sino el hilo que lo ejecuta. Interrumpido es un estado de subproceso. Simplemente lleva al método de suspensión que se abandona. – ubuntudroid

23

Si se arroja una excepción InterruptedException significa que algo quiere interrumpir (generalmente terminar) ese subproceso. Esto se desencadena mediante una llamada al método threads interrupt(). El método de espera detecta eso y arroja una excepción InterruptedException para que el código de captura pueda manejar la solicitud de terminación de inmediato y no tenga que esperar hasta que se agote el tiempo especificado.

Si lo usa en una aplicación de subproceso único (y también en algunas aplicaciones de subprocesos múltiples), esa excepción nunca se desencadenará. Ignorarlo al tener una cláusula de captura vacía no lo recomendaría. El lanzamiento de la InterruptedException borra el estado interrumpido del hilo, por lo que si no se maneja correctamente esa información se pierde. Por lo tanto, propondría ejecutar:

} catch (InterruptedException e) { 
    Thread.currentThread().interrupt(); 
    // code for stopping current task so thread stops 
} 

Lo que establece ese estado nuevamente. Después de eso, termina la ejecución.Este sería un comportamiento correcto, incluso resistente nunca utilizado.

Lo que podría ser mejor es añadir un:

} catch (InterruptedException e) { 
    assert false; 
} 

comunicado al bloque catch. Eso básicamente significa que nunca debe suceder. Entonces, si el código se reutiliza en un entorno donde podría ocurrir, se quejará al respecto.

+4

Las aserciones en Java están [desactivadas de forma predeterminada] (http://stackoverflow.com/a/2758645/1143274). Entonces es mejor lanzar una 'RuntimeException'. –

0

Métodos como sleep() y de la clase Thread pueden arrojar un InterruptedException. Esto sucederá si algún otro thread quisiera interrumpir el thread que está esperando o durmiendo.

Cuestiones relacionadas