Comment tuer un thread Java

1. Introduction

Dans ce bref article, nous aborderons l'arrêt d'un Thread en Java - ce qui n'est pas si simple puisque la méthode Thread.stop () est obsolète.

Comme expliqué dans cette mise à jour d'Oracle, stop () peut entraîner la corruption des objets surveillés.

2. Utilisation d'un drapeau

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

Nous utiliserons un drapeau 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 un en boucle une constante évaluation vrai , nous utilisons un AtomicBoolean et maintenant nous pouvons commencer / exécution d'arrêt en mettant à true / false.

Comme expliqué dans notre introduction aux variables atomiques, l'utilisation d'un AtomicBoolean empêche les conflits dans la définition et la vérification de la variable à partir de différents threads.

3. Interrompre un thread

Que se passe-t-il lorsque sleep () est défini sur un long intervalle ou si nous attendons un verrou qui pourrait ne jamais être libéré?

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

Nous pouvons créer l' interruption () pour ces situations, ajoutons quelques méthodes et un nouveau drapeau à 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); 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); } } 

Nous avons ajouté une méthode interrupt () qui définit notre indicateur en cours d'exécution sur false et appelle la méthode interrupt () du thread de travail .

Si le thread est en veille lors de son appel, sleep () se terminera avec une InterruptedException, comme le ferait tout autre appel de blocage.

Cela renvoie le thread à la boucle et il se terminera car l' exécution est fausse.

4. Conclusion

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

Comme toujours, le code source complet est disponible à l'adresse over sur GitHub.