Come uccidere un thread Java

1. Introduzione

In questo breve articolo, tratteremo l' arresto di un thread in Java, il che non è così semplice poiché il metodo Thread.stop () è deprecato.

Come spiegato in questo aggiornamento da Oracle, stop () può portare al danneggiamento degli oggetti monitorati.

2. Utilizzo di una bandiera

Cominciamo con una classe che crea e avvia un thread. Questa attività non terminerà da sola, quindi abbiamo bisogno di un modo per interrompere quel thread.

Useremo una bandiera atomica per questo:

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 } } }

Piuttosto che avere un ciclo while che valuta una costante true , stiamo usando un AtomicBoolean e ora possiamo avviare / interrompere l'esecuzione impostandolo su true / false.

Come spiegato nella nostra introduzione alle variabili atomiche, l'utilizzo di AtomicBoolean previene i conflitti nell'impostazione e nel controllo della variabile da thread diversi.

3. Interruzione di un thread

Cosa succede quando sleep () è impostato su un intervallo lungo o se stiamo aspettando un blocco che potrebbe non essere mai rilasciato?

Corriamo il rischio di bloccare per un lungo periodo o di non terminare mai in modo pulito.

Possiamo creare l' interrupt () per queste situazioni, aggiungiamo alcuni metodi e un nuovo flag alla classe:

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); } } 

Abbiamo aggiunto un metodo interrupt () che imposta il nostro flag in esecuzione su false e chiama il metodo interrupt () del thread di lavoro .

Se il thread sta dormendo quando viene chiamato, sleep () uscirà con una InterrruptException, come qualsiasi altra chiamata di blocco.

Ciò restituisce il thread al ciclo e verrà chiuso poiché l' esecuzione è falsa.

4. Conclusione

In questo rapido tutorial, abbiamo esaminato come utilizzare una variabile atomica, opzionalmente combinata con una chiamata a interrupt (), per chiudere in modo pulito un thread. Questo è decisamente preferibile alla chiamata al metodo deprecato stop () e al rischio di blocco per sempre e danneggiamento della memoria.

Come sempre, il codice sorgente completo è disponibile su GitHub.