So töten Sie einen Java-Thread

1. Einleitung

In diesem kurzen Artikel behandeln wir das Stoppen eines Threads in Java - was nicht so einfach ist, da die Thread.stop () -Methode veraltet ist.

Wie in diesem Update von Oracle erläutert, kann stop () dazu führen, dass überwachte Objekte beschädigt werden.

2. Verwenden einer Flagge

Beginnen wir mit einer Klasse, die einen Thread erstellt und startet. Diese Aufgabe endet nicht von alleine, daher brauchen wir eine Möglichkeit, diesen Thread zu stoppen.

Wir werden dafür eine Atomflagge verwenden:

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

Anstatt eine while- Schleife zu haben, die eine Konstante true auswertet , verwenden wir einen AtomicBoolean. Jetzt können wir die Ausführung starten / stoppen, indem wir sie auf true / false setzen.

Wie in unserer Einführung zu Atomic Variables erläutert, verhindert die Verwendung eines AtomicBoolean Konflikte beim Festlegen und Überprüfen der Variablen aus verschiedenen Threads.

3. Unterbrechen eines Threads

Was passiert, wenn sleep () auf ein langes Intervall eingestellt ist oder wenn wir auf eine Sperre warten , die möglicherweise nie freigegeben wird?

Wir sind dem Risiko ausgesetzt, für einen längeren Zeitraum zu blockieren oder niemals sauber zu kündigen.

Wir können den Interrupt () für diese Situationen erstellen. Fügen wir der Klasse einige Methoden und ein neues Flag hinzu:

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

Wir haben eine Interrupt () -Methode hinzugefügt , die unser Running- Flag auf false setzt und die Interrupt () -Methode des Arbeitsthreads aufruft .

Wenn der Thread beim Aufrufen in den Ruhezustand wechselt , wird sleep () wie jeder andere blockierende Aufruf mit einer InterruptedException beendet .

Dies gibt den Thread an die Schleife zurück und wird beendet, da die Ausführung falsch ist.

4. Fazit

In diesem kurzen Tutorial haben wir uns angesehen, wie eine atomare Variable, optional kombiniert mit einem Aufruf von interrupt (), verwendet wird , um einen Thread sauber herunterzufahren. Dies ist definitiv dem Aufrufen der veralteten stop () -Methode vorzuziehen und riskiert das Sperren für immer und die Beschädigung des Speichers.

Wie immer ist der vollständige Quellcode auf GitHub verfügbar.