Comment tuer un thread Java

Comment tuer un thread Java

1. introduction

Dans ce bref article,we’ll cover stopping a Thread in Java – which is not that simple since the Thread.stop() method is deprecated.

Comme expliqué dansthis update from Oracle,stop() peut entraîner la corruption des objets surveillés.

2. Utiliser un drapeau

Commençons par une classe qui crée et démarre un fil de discussion. Cette tâche ne se terminera pas d'elle-même, nous avons donc besoin d'un moyen d'arrêter ce fil.

Nous utiliserons un indicateur atomique pour cela:

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

Plutôt que d'avoir une bouclewhile évaluant une constantetrue, nous utilisons unAtomicBoolean et maintenant nous pouvons démarrer / arrêter l'exécution en le définissant surtrue/false.

Comme expliqué dans notreintroduction to Atomic Variables, l'utilisation d'unAtomicBoolean évite les conflits dans la définition et la vérification de la variable de différents threads.

3. Interrompre unThread

Que se passe-t-il lorsquesleep() est défini sur un intervalle long ou si nous attendons unlock qui pourrait ne jamais être publié?

Nous courons le risque de bloquer pendant une longue période ou de ne jamais se terminer proprement.

Nous pouvons créer lesinterrupt() pour ces situations, ajoutons quelques méthodes et un nouvel indicateur à la 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);
        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
        }
    }
}

Nous avons ajouté une méthodeinterrupt() qui définit notre indicateurrunning sur false et appelle la méthodeinterrupt() du thread de travail.

Si le thread est en veille lorsque cela est appelé,sleep() sortira avec unInterruptedException, comme le ferait tout autre appel de blocage.

Cela renvoie le thread à la boucle et il se terminera puisquerunning est faux.

4. Conclusion

Dans ce rapide tutoriel, nous avons examiné comment utiliser une variable atomique, éventuellement combinée avec un appel àinterrupt(), pour arrêter proprement un thread. C'est certainement préférable à l'appel de la méthode obsolètestop() et au risque de se verrouiller à jamais et de corrompre la mémoire.

Comme toujours, le code source complet est disponibleover on GitHub.