1. Introducción
En este breve artículo, cubriremos cómo detener un Thread en Java, lo cual no es tan simple ya que el método Thread.stop () está obsoleto.
Como se explica en esta actualización de Oracle, stop () puede provocar la corrupción de los objetos monitoreados.
2. Usando una bandera
Comencemos con una clase que crea e inicia un hilo. Esta tarea no terminará por sí sola, por lo que necesitamos alguna forma de detener ese hilo.
Usaremos una bandera atómica para eso:
public class ControlSubThread implements Runnable { private Thread worker; private final AtomicBoolean running = new AtomicBoolean(false); private int interval; public ControlSubThread(int sleepInterval) { interval = sleepInterval; } public void start() { worker = new Thread(this); worker.start(); } public void stop() { running.set(false); } public void run() { running.set(true); while (running.get()) { try { Thread.sleep(interval); } catch (InterruptedException e){ Thread.currentThread().interrupt(); System.out.println( "Thread was interrupted, Failed to complete operation"); } // do something here } } }
En lugar de tener un tiempo de bucle evaluar una constante verdadera , estamos usando un AtomicBoolean y ahora podemos comenzar / parar la ejecución mediante el establecimiento de verdadero / falso.
Como se explica en nuestra introducción a las Variables atómicas, el uso de un AtomicBoolean evita conflictos al configurar y verificar la variable de diferentes subprocesos.
3. Interrumpir un hilo
¿Qué sucede cuando sleep () se establece en un intervalo largo o si estamos esperando un bloqueo que quizás nunca se libere?
Nos enfrentamos al riesgo de bloquear durante un período prolongado o de no terminar nunca limpiamente.
Podemos crear la interrupción () para estas situaciones, agreguemos algunos métodos y una nueva bandera a la clase:
public class ControlSubThread implements Runnable { private Thread worker; private AtomicBoolean running = new AtomicBoolean(false); private int interval; // ... public void interrupt() { running.set(false); worker.interrupt(); } boolean isRunning() { return running.get(); } boolean isStopped() { return stopped.get(); } public void run() { running.set(true); stopped.set(false); while (running.get()) { try { Thread.sleep(interval); } catch (InterruptedException e){ Thread.currentThread().interrupt(); System.out.println( "Thread was interrupted, Failed to complete operation"); } // do something } stopped.set(true); } }
Hemos agregado un método interrupt () que establece nuestra bandera en ejecución en falso y llama al método interrupt () del hilo de trabajo .
Si el hilo está durmiendo cuando se llama, sleep () saldrá con una InterruptedException, al igual que cualquier otra llamada de bloqueo.
Esto devuelve el hilo al bucle y se cerrará ya que la ejecución es falsa.
4. Conclusión
En este tutorial rápido, vimos cómo usar una variable atómica, opcionalmente combinada con una llamada a interrupt (), para cerrar limpiamente un hilo. Definitivamente, esto es preferible a llamar al método stop () obsoleto y arriesgarse a bloquear para siempre y dañar la memoria.
Como siempre, el código fuente completo está disponible en GitHub.