método de interrupción no haber apagado JVM

akila:

Yo estaba jugando con el siguiente ejemplo:

public static void interrupted() throws InterruptedException {
    Runnable task = () -> {
        while(true && !Thread.currentThread().isInterrupted()) {
            System.out.println("task executing");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

    Thread thread = new Thread(task);

    thread.start();
    //lets allow spawned thread to run by sleeping main thread for 10 seconds 
    Thread.currentThread().sleep(10000);
    thread.interrupt();
}

cuando corro este método que estaba esperando:

1 que la tarea iniciada a través Ejecutable correría un par de veces y la impresión SOP

2 anterior sería posible desde principal duerme hilo para 10 segundos

3 una vez hilo principal se despierta que llama interrupción en el subproceso generado

4 en la tarea Ejecutable estamos comprobando para isInterrupted por lo que este debe conseguir disparado y dio lugar hilo debe salir de ese modo permitiendo la JVM para salir.

Sin embargo esto no está ocurriendo y espectáculos Eclipse / JVM que el subproceso generado todavía se está ejecutando el bucle while

Aquí está la consola:

task executing
task executing
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at basics.StopEx.lambda$1(StopEx.java:39)
at java.lang.Thread.run(Thread.java:748)
task executing
task executing
task executing
task executing
........

Los documentos java respecto interrupción sí parece indicar que llama 'sueño' causaría un comportamiento diferente (se destaca a continuación) - ¿Puede alguien arrojar alguna luz sobre lo que está pasando aquí exactamente y por qué?

Interrumpe este hilo.

A menos que el hilo actual está interrumpiendo sí, que siempre está permitida, se invoca el método checkAccess de este hilo, que puede causar una SecurityException a ser lanzado.

Si este hilo está bloqueado en una invocación de los métodos de la clase Object wait (), espera (tiempo), o de espera (tiempo, int), o de la unión (), join (largo), se unen (largo, int) , sueño (tiempo), o el sueño (tiempo, int), métodos de esta clase, entonces su estado de alarma se borrarán y que recibirán un InterruptedException.

Si este hilo está bloqueado en una operación de E / S sobre un InterruptibleChannel entonces el canal se cierra, el estado de interrupción de la rosca será conjunto, y el hilo recibirá una java.nio.channels.ClosedByInterruptException.

Si este hilo se bloquea en un java.nio.channels.Selector entonces de estado de interrupción de la rosca se establecerá y volverá inmediatamente de la operación de selección, posiblemente con un valor distinto de cero, tal como si se invoca el método de activación del selector.

Si ninguna de las condiciones anteriores mantenga a continuación, se establecerá el estado de interrupción de este hilo.

Interrupción de un hilo que no es necesario vivos no tienen ningún efecto.

rzwitserloot:

Es debido a la forma en que el indicador de interrupción trabaja para un hilo.

Cuando se interrumpe un hilo, básicamente, sólo una cosa que sucede: el indicador de interrupción se establece, y eso es todo lo que sucede. Le corresponde entonces al código que este hilo se está ejecutando ya sea que realmente hace cosas.

La idea general es que aborta lo que está haciendo si se puede y tirar alguna excepción razonable.

Unos métodos incorporados en java garantía de que esto es exactamente cómo funcionan. Se puede reconocer fácilmente: Todos ellos se declaran a tirar InterruptedException. Hay muchos métodos donde el comportamiento cuando no está definido intencionadamente interrumpir (que depende del sistema operativo): Todos aquellos bloqueo de E / S métodos actúan de esta manera. Si se encuentra en una red bloqueo de lectura y se interrumpe el hilo que está bloqueado en la lectura, que podrían dar lugar a una IOException en la llamada de lectura, o no ...

Más importante aún, cuando 'tratar' con una interrupción (y abortar + lanzar una excepción es tratar con él!), La bandera se borra .

Tenga en cuenta que la comprobación de la bandera ya lo aclara, si se utiliza la forma estándar de la comprobación de que, lo que es Thread.interrupted(). Indicador de interrupción Este método comprueba su propio hilo y despejó . Utilice la siguiente: El hecho de que usted ha escrito una ifdeclaración o lo que sea para hacer frente a los medios de interrupción que se ocuparon de ello.

Por lo tanto, si desea devolver sólo en respuesta a ser interrumpido, el código correcto es:

    Runnable task = () -> {
        while (!Thread.interrupted()) {
            System.out.println("Executing");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                return;
            }
        }
    };

Este método solo se cerrará con independencia del momento de la interrupción ocurre. En el caso del 99,99%, mientras que el bloqueo de itll suceda en el sueño. A continuación, la bandera será falsa, y la excepción. En el caso poco probable de que ocurra mientras el procesamiento fuera de ella, la condición mientras se recogerlo.

Tenga en cuenta que si usted tiene la bandera de interrupción levantó y se llama a un método como Thread.sleep, ese método al instante terminar la ejecución en la limpieza de la bandera y tirar InterruptedException. No importa donde sucede la interrupción, el ejemplo anterior hará lo mismo (en silencio salir el método de ejecución, y la bandera de interrupción se borrará).

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=232171&siteId=1
Recomendado
Clasificación