So beenden Sie einen Java-Thread

So beenden Sie einen Java-Thread

1. Einführung

In diesem kurzen Artikel werdenwe’ll cover stopping a Thread in Java – which is not that simple since the Thread.stop() method is deprecated.

Wie inthis update from Oracle, erläutert, kannstop() 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 dass einewhile-Schleife eine Konstantetrue auswertet, verwenden wir eineAtomicBoolean und können jetzt die Ausführung starten / stoppen, indem wir sie auftrue/false. setzen

Wie in unserenintroduction to Atomic Variables erläutert, verhindert die Verwendung vonAtomicBoolean Konflikte beim Setzen und Überprüfen der Variablen aus verschiedenen Threads.

3. Unterbrechen vonThread

Was passiert, wennsleep() auf ein langes Intervall eingestellt ist oder wenn wir auflockwarten, die möglicherweise nie freigegeben werden?

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

Wir können dieinterrupt() 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);
        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
        }
    }
}

Wir haben eineinterrupt()-Methode hinzugefügt, die unserrunning-Flag auf false setzt und dieinterrupt()-Methode des Arbeitsthreads aufruft.

Wenn der Thread beim Aufrufen in den Ruhezustand wechselt, wirdsleep() wie bei jedem anderen blockierenden Aufruf mitInterruptedException, beendet.

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

4. Fazit

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

Wie immer ist der vollständige Quellcodeover on GitHub verfügbar.