« Salut Amigo !

"Tout ce qui est nouveau est juste quelque chose d'ancien que nous avons oublié. Aujourd'hui, je vais parler de l'arrêt des threads. J'espère que vous avez déjà oublié comment fonctionne la méthode interrupt()."

"Oui, Ellie, je l'ai complètement oublié."

"Génial. Alors je te rappellerai."

"En Java, si quelqu'un veut arrêter un thread en cours d'exécution, il peut le signaler au thread. Pour ce faire, vous devez définir la variable isInterrupted cachée de l'objet Thread sur true."

"Chaque Thread a une méthode interrupt(), qui est utilisée pour définir cet indicateur. Lorsque la méthode interrupt () est appelée, la variable isInterrupted à l'intérieur de l'objet Thread est définie sur true."

"Et lorsque la méthode Thread.sleep() ou join() est appelée sur un thread, la méthode vérifie si l'indicateur isInterrupted est défini pour le thread actuel. Si cet indicateur est défini (la variable isInterrupted vaut true), alors les méthodes lancer une InterruptedException ."

"Ici, je vais vous rappeler un vieil exemple :"

Code Description
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
La méthode run de Clock récupère l'objet Thread pour le thread actuel.

La classe Clock écrit le mot "Tick" sur la console une fois par seconde tant que la variable isInterrupt du thread actuel est fausse.

Lorsque isInterrupt devient true, la méthode run se termine.

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clockThread.interrupt();
}
Le thread principal démarre un thread enfant (horloge) qui doit s'exécuter indéfiniment.

Attendez 10 secondes et annulez la tâche en appelant la méthode d'interruption.

Le fil conducteur termine son travail.

Le fil de l'horloge termine son travail.

"Ici, nous utilisons la méthode sleep dans le cadre d'une boucle infinie dans la méthode run . Dans la boucle, la variable isInterrupt est vérifiée automatiquement. Si un thread appelle la méthode sleep , la méthode vérifie d'abord si isInterrupt est vrai pour ce thread (le qui a appelé la méthode sleep). Si c'est vrai, alors la méthode ne dormira pas. Au lieu de cela, elle lève une InterruptedException ."

"Mais dans cet exemple, nous vérifions constamment la variable isInterrupted dans la condition de la boucle."

"Je me souviens qu'il y avait des raisons pour lesquelles nous ne pouvions pas utiliser cette approche. Pourriez-vous me le rappeler ?"

" Premièrement , la méthode run n'a pas toujours de boucle. La méthode peut simplement consister en quelques dizaines d'appels à d'autres méthodes. Dans ce cas, vous devrez ajouter une vérification isInterrupted avant chaque appel de méthode. "

" Deuxièmement , certaines méthodes impliquant de nombreuses actions différentes peuvent prendre très longtemps à s'exécuter."

" Troisièmement , lancer une exception ne remplace pas la vérification isInterrupted. C'est juste un ajout pratique. L'exception levée vous permet de dérouler rapidement la pile d'appels vers la méthode run elle-même."

" Quatrièmement , la méthode du sommeil est beaucoup utilisée. Il s'avère que cette méthode utile est renforcée par une vérification implicite qui n'est pas moins utile. C'est  comme si personne n'avait spécifiquement ajouté la vérification, mais elle est là.  C'est super précieux quand vous 'utilise le code de quelqu'un d'autre et vous ne pouvez pas ajouter la vérification vous-même."

" Cinquièmement , la vérification supplémentaire ne dégrade pas les performances. L'appel de la méthode sleep signifie que le thread ne devrait rien faire (sauf dormir), donc le travail supplémentaire ne dérange personne."

"C'est exactement ce que tu as dit précédemment."

"Et qu'en est-il de votre déclaration, « Personne ne peut garantir qu'un thread sera arrêté. Seul un thread peut s'arrêter lui-même. » Pouvez-vous expliquer cela ? »

"Bien sûr."

"Auparavant, dans les premières versions de Java, les threads avaient une méthode stop (). Et lorsque vous l'appeliez, la JVM arrêtait réellement le thread. Mais si un thread faisait quelque chose en dehors de la JVM (par exemple, écrire dans un fichier ou appeler Fonctions du système d'exploitation) lorsqu'il a été interrompu de cette façon, l'interruption a causé beaucoup de problèmes, tels que des fichiers non fermés, des ressources système non publiées, etc."

"Une assemblée générale des créateurs de Java a décidé de supprimer la méthode d'arrêt forcé des threads. Maintenant, tout ce que nous pouvons faire est de définir un certain drapeau (isInterrupted) et d'espérer que le code du thread a été écrit correctement, afin que ce drapeau soit traité. Ce drapeau est comme un panneau qui dit : "Enfilez, arrêtez, s'il vous plaît. C'est très important !". Mais qu'il s'arrête ou non, cela ne regarde que lui."

"Mais qu'en est-il de l'InterruptedException?"

"Et si le code en cours d'exécution sur ce thread contient un tas de blocs try-catch ? Même si une InterruptedException se produit quelque part, il n'y a certainement aucune garantie qu'un try-catch ne l'attrapera pas et l'oubliera. Il n'y a donc aucune garantie que le le fil va s'arrêter."

"Une autre chose est que les threads sont déjà considérés comme de la programmation de bas niveau. Mais je vous en parlerai la prochaine fois."

« Tu n'es pas Ellie, tu es Shéhérazade ! »

« Alors, Amigo ! Est-ce que tout est clair dans la leçon en cours ? »

"Ouais."

"D'accord, bien."