¿Podría explicar qué java.lang.Thread.interrupt()
hace cuando se invoca?
¿Podría explicar qué java.lang.Thread.interrupt()
hace cuando se invoca?
Respuestas:
Thread.interrupt()
establece el estado / indicador interrumpido del hilo objetivo. Luego, el código que se ejecuta en ese hilo de destino PUEDE sondear el estado interrumpido y manejarlo adecuadamente. Algunos métodos que bloquean Object.wait()
pueden consumir el estado interrumpido inmediatamente y generar una excepción apropiada (generalmente InterruptedException
)
La interrupción en Java no es preventiva. Dicho de otro modo, ambos hilos deben cooperar para procesar la interrupción correctamente. Si el hilo objetivo no sondea el estado interrumpido, la interrupción se ignora efectivamente.
El sondeo se realiza a través del Thread.interrupted()
método que devuelve el estado interrumpido del subproceso actual Y borra ese indicador de interrupción. Por lo general, el hilo podría hacer algo como lanzar InterruptedException.
EDITAR (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()
` yThread.join()
java.util.concurrent
estructurasInterruptedException
, sino que usa ClosedByInterruptException
.EDITAR (de la respuesta de @ thomas-pornin a exactamente la misma pregunta 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()
eso es más como disparar el hilo con un rifle de asalto.
¿Qué es la 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 mediante un indicador interno conocido como estado de interrupción. Invocar Thread.interrupt establece esta bandera. Cuando un subproceso busca una interrupción invocando el método estático Thread.interrupted, el estado de la 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. Primero se invoca el método checkAccess de este hilo, lo que puede provocar 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, entonces su estado de interrupción se borrará y recibirá una InterruptedException.
Si este hilo se bloquea en una operación de E / S en un canal interrumpible, entonces el canal se cerrará, se establecerá el estado de interrupción del hilo y el hilo recibirá una ClosedByInterruptException.
Si este subproceso está bloqueado en un selector, se establecerá el estado de interrupción del subproceso y volverá inmediatamente de 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 ninguna de las condiciones anteriores se cumple, se establecerá el estado de interrupción de este hilo.
Mira esto para comprender completamente lo mismo:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Si el hilo objetivo ha estado esperando (llamando wait()
, o algún otro método relacionado que esencialmente haga lo mismo, como sleep()
), se interrumpirá, lo que significa que deja de esperar lo que estaba esperando y en su lugar recibe una InterruptedException.
Depende completamente del hilo (el código que llamó wait()
) 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 cerrarse. Pero de nuevo, esto es solo una convención.
Para completar, además de las otras respuestas, si el hilo se interrumpe antes de bloques en Object.wait(..)
o Thread.sleep(..)
etc., esto es equivalente a que ser interrumpido inmediatamente después de 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 bucle como el siguiente, y la interrupción ocurre en el momento exacto en que el control se ha ido Thread.sleep(..)
y está dando la vuelta al bucle, la excepción seguirá ocurriendo. Por lo tanto, es perfectamente seguro confiar en que la excepción InterruptedException sea lanzada de manera confiable después de que el hilo haya sido interrumpido :
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
Thread.interrupt()
establece el estado / indicador interrumpido del subproceso de destino en verdadero, que cuando se marca con Thread.interrupted()
ayuda puede ayudar a detener el subproceso sin fin. Consulte http://www.yegor256.com/2015/10/20/interrupted-exception.html
La interrupción de subprocesos se basa en el estado de interrupción del indicador . Para cada subproceso, el valor predeterminado del estado de interrupción se establece en falso . Cada vez que se llama al método interrupt () en el hilo, el estado de interrupción se establece en verdadero .
interrupción pública nula ()
Interrumpe este hilo.
A menos que el subproceso actual se interrumpa, lo que siempre está permitido, se invoca el método checkAccess de este subproceso, lo que puede provocar una excepción 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 excepción interrumpida.
Si este hilo se bloquea en una operación de E / S en un canal interrumpible, entonces el canal se cerrará, se establecerá el estado de interrupción del hilo y el hilo recibirá una ClosedByInterruptException.
Si este subproceso está bloqueado en un selector, se establecerá el estado de interrupción del subproceso y volverá inmediatamente de 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 ninguna de las condiciones anteriores se cumple, se establecerá el estado de interrupción de este hilo.
Interrumpir un hilo que no está vivo no necesita tener ningún efecto.
Throws: SecurityException - si el hilo actual no puede modificar este hilo
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. Una muy buena referencia: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
El método Thread.interrupt () establece el indicador interno de "estado de interrupción". Por lo general, ese indicador se verifica mediante el método Thread.interrupted ().
Por convención, cualquier método que exista a través de InterruptedException debe borrar el indicador de estado de interrupción.