threads thread run method how example java multithreading

run - threads java



¿Qué hace java.lang.Thread.interrupt()? (8)

La interrupción de subprocesos se basa en el estado de interrupción de bandera. Para cada valor predeterminado de la secuencia de estado de interrupción se establece en falso . Cuando se invoca el método de interrupción () en el hilo, el estado de interrupción se establece en verdadero .

  1. Si el estado de interrupción = verdadero (interrupción () ya llamó al hilo), ese hilo en particular no puede ir a dormir. Si se invoca sleep en esa secuencia, se lanza una excepción interrumpida. Después de arrojar una excepción nuevamente, la bandera se establece en falso.
  2. Si el hilo ya está durmiendo y se invoca a la interrupción () , el hilo saldrá del estado de suspensión y emitirá una excepción interrumpida.

¿Podría explicar qué hace java.lang.Thread.interrupt() cuando se invoca?


Para completar, además de las otras respuestas, si el hilo se interrumpe antes de que se bloquee en Object.wait(..) o Thread.sleep(..) etc., esto es equivalente a que se interrumpa inmediatamente después del bloqueo en ese método , como muestra el siguiente ejemplo.

public class InterruptTest { public static void main(String[] args) { Thread.currentThread().interrupt(); printInterrupted(1); Object o = new Object(); try { synchronized (o) { printInterrupted(2); System.out.printf("A Time %d/n", System.currentTimeMillis()); o.wait(100); System.out.printf("B Time %d/n", System.currentTimeMillis()); } } catch (InterruptedException ie) { System.out.printf("WAS interrupted/n"); } System.out.printf("C Time %d/n", System.currentTimeMillis()); printInterrupted(3); Thread.currentThread().interrupt(); printInterrupted(4); try { System.out.printf("D Time %d/n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("E Time %d/n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted/n"); } System.out.printf("F Time %d/n", System.currentTimeMillis()); printInterrupted(5); try { System.out.printf("G Time %d/n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("H Time %d/n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted/n"); } System.out.printf("I Time %d/n", System.currentTimeMillis()); } static void printInterrupted(int n) { System.out.printf("(%d) Am I interrupted? %s/n", n, Thread.currentThread().isInterrupted() ? "Yes" : "No"); } }

Salida:

$ javac InterruptTest.java $ java -classpath "." InterruptTest (1) Am I interrupted? Yes (2) Am I interrupted? Yes A Time 1399207408543 WAS interrupted C Time 1399207408543 (3) Am I interrupted? No (4) Am I interrupted? Yes D Time 1399207408544 WAS interrupted F Time 1399207408544 (5) Am I interrupted? No G Time 1399207408545 H Time 1399207408668 I Time 1399207408669

Implicación: si realiza un ciclo como el siguiente, y la interrupción se produce en el momento exacto en que el control ha salido de Thread.sleep(..) y va por el ciclo, la excepción seguirá ocurriendo. Por lo tanto, es perfectamente seguro confiar en que InterruptedException se lanzará de manera confiable después de que el hilo se haya interrumpido :

while (true) { try { Thread.sleep(10); } catch (InterruptedException ie) { break; } }


Si el subproceso específico ha estado esperando (al llamar a wait() u otros métodos relacionados que esencialmente hacen lo mismo, como sleep() ), se interrumpirá, lo que significa que dejará de esperar lo que estaba esperando y recibir una interruptedException en su lugar.

Depende completamente del hilo en sí (el código que llamó a wait() ) para decidir qué hacer en esta situación. No termina automáticamente el hilo.

A veces se usa en combinación con una bandera de terminación. Cuando se interrumpe, el hilo puede verificar esta bandera, y luego se apaga solo. Pero, nuevamente, esto es solo una convención.



Thread.interrupt() establece el estado / indicador interrumpido de la Thread.interrupt() de destino. Entonces, el código que se ejecuta en ese hilo objetivo PUEDE sondear el estado interrumpido y manejarlo apropiadamente. Algunos métodos que bloquean, como Object.wait() pueden consumir el estado interrumpido inmediatamente y arrojar una excepción apropiada (generalmente InterruptedException )

La interrupción en Java no es preventiva. Dicho de otra manera, ambos hilos tienen que cooperar para procesar la interrupción adecuadamente. Si el hilo objetivo no sondea el estado interrumpido, la interrupción se ignora de manera efectiva.

El sondeo ocurre a través del método Thread.interrupted() que devuelve el estado interrumpido del hilo actual Y borra el indicador de interrupción. Por lo general, el hilo puede hacer algo como lanzar InterruptedException.

EDITAR (a partir de los comentarios de Thilo): algunos métodos API han incorporado el manejo de interrupciones. De la parte superior de mi cabeza esto incluye.

  • Object.wait()/Thread.sleep()
  • La mayoría de las estructuras java.util.concurrent
  • Java NIO (pero no java.io) y NO usa InterruptedException , sino que usa ClosedByInterruptException .

EDITAR (de la respuesta de @thomas-pornin a la misma pregunta exactamente para completar)

La interrupción del hilo es una forma suave de empujar un hilo. Se usa para dar a los hilos la oportunidad de salir limpiamente , en lugar de Thread.stop() que es más como disparar el hilo con un rifle de asalto.



¿Qué es interrupción?

Una interrupción es una indicación a un hilo de que debe detener lo que está haciendo y hacer otra cosa. Depende del programador decidir exactamente cómo responde un hilo a una interrupción, pero es muy común que el hilo termine.

¿Cómo se implementa?

El mecanismo de interrupción se implementa utilizando un indicador interno conocido como estado de interrupción. La invocación de Thread.interrupt establece esta bandera. Cuando un hilo comprueba una interrupción invocando el método estático Thread.interrupted, el estado de interrupción se borra. El Thread.isInterrupted no estático, que es utilizado por un hilo para consultar el estado de interrupción de otro, no cambia el indicador de estado de interrupción.

Cita de Thread.interrupt() API :

Interrumpe este hilo. En primer lugar, se invoca el método checkAccess de este hilo, que puede provocar el lanzamiento de una SecurityException.

Si este hilo está bloqueado en una invocación de los métodos wait (), wait (long) o wait (long, int) de la clase Object, o de join (), join (long), join (long, int) , sleep (long), o sleep (long, int), métodos de esta clase, luego se borrará su estado de interrupción y recibirá una interruptedException.

Si este subproceso se bloquea en una operación de E / S sobre un canal interrumpible, el canal se cerrará, se establecerá el estado de interrupción del subproceso y el subproceso recibirá una excepción ClosedByInterruptException.

Si este hilo está bloqueado en un Selector, se establecerá el estado de interrupción del hilo y éste retornará inmediatamente desde la operación de selección, posiblemente con un valor distinto de cero, como si se invocara el método de activación del selector.

Si no se cumple ninguna de las condiciones anteriores, se establecerá el estado de interrupción de este subproceso.

Mira esto para una comprensión completa sobre el mismo:

http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html


interrupción de vacío público ()

Interrumpe este hilo.

A menos que el hilo actual se esté interrumpiendo, lo que siempre está permitido, se invoca el método checkAccess de este hilo, que puede provocar que se genere una SecurityException.

Si este hilo está bloqueado en una invocación de los métodos wait (), wait (long) o wait (long, int) de la clase Object, o de join (), join (long), join (long, int) , sleep (long), o sleep (long, int), métodos de esta clase, luego se borrará su estado de interrupción y recibirá una interruptedException.

Si este subproceso se bloquea en una operación de E / S sobre un canal interrumpible, el canal se cerrará, se establecerá el estado de interrupción del subproceso y el subproceso recibirá una excepción ClosedByInterruptException.

Si este hilo está bloqueado en un Selector, se establecerá el estado de interrupción del hilo y éste retornará inmediatamente desde la operación de selección, posiblemente con un valor distinto de cero, como si se invocara el método de activación del selector.

Si no se cumple ninguna de las condiciones anteriores, se establecerá el estado de interrupción de este subproceso.

La interrupción de un hilo que no está vivo no tiene por qué tener ningún efecto.

Lanzamientos: SecurityException: si el hilo actual no puede modificar este hilo