2010-12-15 13 views
5
package util.concurrent; 

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class ShutdownDemo { 
public static void main(String[] args) throws InterruptedException{ 
    ExecutorService executor = Executors.newSingleThreadExecutor(); 

    executor.execute(new Runnable(){ 

    @Override 
    public void run() { 
    while(true){ 
    System.out.println("-- test --"); 
    } 
    } 

    }); 

    TimeUnit.SECONDS.sleep(3); 

    executor.shutdownNow(); 
} 
} 

Ya he invocado el método shutdownNow, ¿por qué la consola continúa imprimiendo "- test -" ??Por qué el método ExecutorService.shutdownNow no puede detener el hilo

Respuesta

1

Desde el JavaDocs, el método ExecutorService # shutdownNow no garantiza que realmente detenga la ejecución de trabajos. Es mucho mejor que mutes una variable de estado que los trabajos de larga ejecución verifican periódicamente y, al detectar el cambio, cierran su ciclo de ejecución.

+1

Esto es exagerado. Su variable de estado no es diferente de la variable de estado ya proporcionada por Thread.interrupted. Se comportará de la misma manera. Si bien puedes escribir código que asegure que shutdownNow() no se complete, que es culpa del autor, si sigues las reglas, dije que se cerrará eventualmente. Las llamadas a la red eventualmente agotan el tiempo de espera, pero aunque ese tiempo de espera no ha expirado, el hilo tendrá que esperar hasta que se produzca la excepción de tiempo de espera excedido. Esto también se aplica a una variable de estado compartida. – chubbsondubs

10

Salida Thread.stop() en Javadoc de la razón completo:

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop()

En esencia, el hilo debe parar por sí mismo con el fin de su programa para mantenerse a salvo. Solo detener un hilo puede dejar los programas en un estado impredecible donde los bloqueos que posee el hilo no se liberan y los recursos no se devuelven al sistema operativo. Finalmente, dejando su programa abierto a bloqueos muertos, pérdidas de memoria que no se pueden liberar y que también pueden afectar la estabilidad del sistema operativo. Esto realmente no es diferente si estuvieras en C o en cualquier otro idioma porque detener los hilos nativos tiene estos problemas. Recuerde que los hilos no son procesos que comparten memoria y estado con otros hilos, por lo que deben comportarse y cooperar.

Java funciona interrumpiendo hilos en lugar de matar hilos, por lo que los hilos deben ajustarse a este modelo cuando los escriba. Por lo tanto, mientras (verdadero) en su programa es una mala práctica. En su lugar, necesita ver si su hilo ha sido interrumpido y apagarlo por sí mismo. Ya sea con Thread.sleep y manejando la InterruptedException correctamente. O revisando Thread.isInterrupted() en su ciclo while.

+0

Pero esta es una instancia de 'Runnable' - ¿dónde podemos obtener' Thread.isInterrupted() '? Además, si 'shutdownNow()' intenta interrumpir nuestro hilo mientras no está durmiendo, solo establecerá el indicador interrumpido y no generará 'InterruptedException' cuando' duerma() 'nuevamente (si entiendo los documentos correctamente). – drevicko

+1

Siempre puede obtener el hilo ejecutando cualquier sección de ese código utilizando Thread.currentThread(). IsInterrupted(). Recuerde que una vez que se interrumpe un hilo, cualquier sleep() o wait() generará una interruptedException. – chubbsondubs

+0

Genial, gracias (: Solo para asegurarme de haber entendido bien, si nuestros hilos 'interrupt()' se llaman y no estamos en modo sleep() ing, luego ''sleep()' por un bit, ' InterruptedException' se genera inmediatamente? Es de suponer que esto es parte de la especificación de Java y debe implementarse en todas las VM/bibliotecas estándar? – drevicko

Cuestiones relacionadas