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

Resuelto oneat asked hace 14 años • 9 respuestas

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

oneat avatar Aug 28 '10 15:08 oneat
Aceptado

Thread.interrupt()establece el estado/indicador de interrupción del hilo de destino. Luego, el código que se ejecuta en ese hilo de destino PUEDE sondear el estado de interrupción y manejarlo adecuadamente. Algunos métodos que bloquean, como los que Object.wait()pueden consumir el estado de interrupción inmediatamente y generar una excepción apropiada (generalmente InterruptedException)

La interrupción en Java no es preventiva. Dicho de otra manera, ambos subprocesos deben cooperar para procesar la interrupción correctamente. Si el hilo de destino no sondea el estado de interrupción, la interrupción se ignora de manera efectiva.

El sondeo se produce a través del Thread.interrupted()método que devuelve el estado de interrupción del hilo 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 tienen incorporado el manejo de interrupciones. De la parte superior de mi cabeza esto incluye.

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

EDITAR (de la respuesta de @thomas-pornin a exactamente la misma pregunta para que esté completa)

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

Mike Q avatar Aug 28 '2010 08:08 Mike Q

¿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 este indicador. Cuando un subproceso busca una interrupción invocando el método estático Thread.interrupted, se borra el estado de la interrupción. El Thread.isInterrupted no estático, que utiliza un subproceso 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 que se lance 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 los métodos 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 subproceso 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 subproceso y el subproceso recibirá una excepción ClosedByInterruptException.

Si este hilo está bloqueado en un Selector, entonces se establecerá el estado de interrupción del hilo y regresará 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.

Consulte esto para comprender completamente lo mismo:

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

YoK avatar Aug 28 '2010 08:08 YoK

Si el hilo objetivo ha estado esperando (llamando a wait(), o algún otro método relacionado que esencialmente hace lo mismo, como sleep()), será interrumpido, lo que significa que deja de esperar lo que estaba esperando y recibe una InterruptedException en su lugar.

Depende completamente del hilo mismo (el código que llamó wait()) decidir qué hacer en esta situación. No finaliza automáticamente el hilo.

A veces se utiliza en combinación con un indicador de terminación. Cuando se interrumpe, el hilo podría verificar este indicador y luego cerrarse. Pero repito, esto es sólo una convención.

Thilo avatar Aug 28 '2010 08:08 Thilo

Para completar, además de las otras respuestas, si el hilo se interrumpe antes de bloquearse en Object.wait(..)o Thread.sleep(..)etc., esto equivale a que se interrumpa inmediatamente después de bloquearse en ese método , como se muestra en 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");
    }
}

Producción:

$ 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 se produce en el momento exacto en que el control ha salido Thread.sleep(..)y está dando la vuelta al bucle, la excepción seguirá ocurriendo. Por lo tanto, es perfectamente seguro confiar en que la InterruptedException se lance de manera confiable después de que se haya interrumpido el hilo :

while (true) {
    try {
        Thread.sleep(10);
    } catch (InterruptedException ie) {
        break;
    }
}
Evgeni Sergeev avatar May 04 '2014 12:05 Evgeni Sergeev