¿Cómo se mata un hilo en Java?


¿Cómo se mata un java.lang.Thread en Java?

Author: Michael, 2009-03-22

14 answers

Vea este hilo de Sun sobre por qué dejaron de ser usados Thread.stop(). Entra en detalles sobre por qué este era un mal método y lo que se debe hacer para detener de forma segura los hilos en general.

La forma en que recomiendan es usar una variable compartida como un indicador que le pide al hilo de fondo que se detenga. Esta variable puede ser establecida por un objeto diferente que solicita la terminación del subproceso.

 169
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-04 19:14:48

Generalmente no lo haces..

Le pides que interrumpa lo que esté haciendo usando el hilo .interrupción() (javadoc enlace)

Una buena explicación de por qué está en el javadoc aquí (enlace de java technote)

 123
Author: Fredrik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-26 10:33:22

En Java los hilos no se matan, pero la detención de un hilo se realiza de una manera cooperativa . Se le pide al hilo que termine y el hilo puede apagarse correctamente.

A menudo se usa un campo volatile boolean que el subproceso comprueba periódicamente y termina cuando se establece en el valor correspondiente.

I no utilizar un boolean para comprobar si el hilo debería terminar. Si usa volatile como modificador de campo, esto funcionará de manera confiable, pero si su el código se vuelve más complejo, ya que en su lugar utiliza otros métodos de bloqueo dentro del bucle while, podría suceder que su código no termine en absoluto o al menos tome más tiempo como desee.

Ciertos métodos de biblioteca de bloqueo admiten interrupciones.

Cada hilo ya tiene una bandera booleana estado interrumpido y deberías hacer uso de ella. Se puede implementar así:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

Código Fuente adaptado de Java Concurrency in Practice . Dado que el método cancel() es público, puede permitir que otro hilo invoque este método como desee.

 62
Author: Konrad Reiche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-08 11:50:29

Una forma es establecer una variable de clase y usarla como centinela.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

Establezca una variable de clase externa, es decir, flag = true en el ejemplo anterior. Establece en false para 'matar' el hilo.

 18
Author: karim79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-11 08:54:09

Hay una manera de hacerlo. Pero si tuvieras que usarlo, o eres un mal programador o estás usando un código escrito por malos programadores. Por lo tanto, usted debe pensar en dejar de ser un mal programador o dejar de usar este código malo. Esta solución es solo para situaciones en las QUE NO HAY OTRA MANERA.

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
 10
Author: VadimPlatonov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-23 12:45:15

Quiero agregar varias observaciones, basadas en los comentarios que se han acumulado.

  1. Hilo.stop() detendrá un subproceso si el administrador de seguridad lo permite.
  2. Hilo.stop() es peligroso. Dicho esto, si está trabajando en un entorno JEE y no tiene control sobre el código que se llama, puede ser necesario.
  3. Nunca debe detener detener un subproceso de trabajo de contenedor. Si desea ejecutar código que tiende a colgarse, (con cuidado) inicie un nuevo hilo de demonio y supervisar, matando si es necesario.
  4. stop() crea un nuevo error ThreadDeath en el subproceso que llama ay luego hace que ese Error se aplique al subproceso destino. Por lo tanto, el seguimiento de la pila generalmente no tiene valor.
  5. En JRE 6, stop() comprueba con el administrador de seguridad y luego llama a stop1() que llama a stop0(). stop0() es código nativo.
 7
Author: Steve11235,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-25 18:35:36

Votaría por Thread.stop().

Por ejemplo, tiene una operación de larga duración (como una solicitud de red). Supuestamente está esperando una respuesta, pero puede tomar tiempo y el usuario navegó a otra interfaz de usuario. Este hilo de espera ahora es a) inútil b) problema potencial porque cuando obtendrá el resultado, es completamente inútil y activará devoluciones de llamada que pueden conducir a un número de errores.

Todo eso y puede hacer un procesamiento de respuestas que podría ser intenso para la CPU. Y tú, como desarrollador, ni siquiera puede detenerlo, porque no puede lanzar if (Thread.currentThread().isInterrupted()) líneas en todo el código.

Así que la incapacidad de detener con fuerza un hilo es raro.

 5
Author: Anfet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-18 11:59:34

La pregunta es bastante vaga. Si quieres decir "cómo escribo un programa para que un hilo deje de ejecutarse cuando quiero", entonces varias otras respuestas deberían ser útiles. Pero si quieres decir "Tengo una emergencia con un servidor que no puedo reiniciar en este momento y solo necesito un hilo en particular para morir, pase lo que pase", entonces necesita una herramienta de intervención para que coincida con herramientas de monitoreo como jstack.

Para este propósito he creado jkillthread. Consulte sus instrucciones de uso.

 4
Author: Jesse Glick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-05 16:07:53

Por supuesto, existe el caso en el que está ejecutando algún tipo de código no completamente confiable. (Yo personalmente tengo esto al permitir que los scripts subidos se ejecuten en mi entorno Java. Sí, hay una campana de alarma de seguridad sonando por todas partes, pero es parte de la aplicación.) En este desafortunado caso, en primer lugar, está simplemente siendo esperanzado al pedir a los escritores de guiones que respeten algún tipo de señal booleana de ejecución/no ejecución. Su único a prueba de fallos decente es llamar al método stop en el hilo si, digamos que es más largo que un tiempo de espera.

Pero, esto es simplemente "decente", y no absoluto, porque el código podría atrapar el error ThreadDeath (o cualquier excepción que lance explícitamente), y no volver a generarlo como se supone que debe hacer un hilo caballeroso. Por lo tanto, la conclusión es AFAIA no hay absoluta a prueba de fallos.

 3
Author: mlohbihler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-20 19:25:03

No hay manera de matar con gracia un hilo.

Puede intentar interrumpir el hilo, una estrategia de commons es usar una píldora venenosa para enviar un mensaje al hilo para que se detenga

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = “stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

Http://anandsekar.github.io/cancel-support-for-threads /

 2
Author: Anand Rajasekar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-20 14:37:32

Generalmente no se mata, detiene o interrumpe un hilo (o se comprueba si está interrumpido ()), pero se deja terminar naturalmente.

Es simple. Puedes usar cualquier bucle junto con la variable booleana (volátil) dentro del método run () para controlar la actividad del hilo. También puede volver del subproceso activo al subproceso principal para detenerlo.

De esta manera matas un hilo con gracia :) .

 2
Author: pnti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-23 23:05:42

Los intentos de terminación abrupta de subprocesos son prácticas de programación mal conocidas y evidencia de un diseño de aplicación deficiente. Todos los subprocesos en la aplicación multiproceso comparten explícita e implícitamente el mismo estado de proceso y se ven obligados a cooperar entre sí para mantenerlo consistente, de lo contrario su aplicación será propensa a los errores que serán muy difíciles de diagnosticar. Por lo tanto, es responsabilidad del desarrollador proporcionar una garantía de dicha consistencia a través de una aplicación cuidadosa y clara diseño.

Hay dos soluciones principales correctas para las terminaciones de hilos controlados:

  • Uso de la bandera volátil compartida
  • Uso del par de hilos.interrupt () y Thread.métodos interrumpidos ().

Se puede encontrar una explicación buena y detallada de los problemas relacionados con la terminación abrupta de los hilos, así como ejemplos de soluciones incorrectas y correctas para la terminación de los hilos controlados aquí:

Https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

 1
Author: ZarathustrA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-18 09:32:37

Aquí hay un par de buenas lecturas sobre el tema:

¿Qué Haces Con La Excepción Interrumpida?

Cerrar los hilos limpiamente

 1
Author: splashout,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-04 19:42:20

No conseguí que la interrupción funcionara en Android, así que usé este método, funciona perfectamente:

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }
 0
Author: Mindborg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-07 10:48:17