CodeGym /Blog Java /Random-FR /Multithreading : ce que font les méthodes de la classe Th...
Auteur
Pavlo Plynko
Java Developer at CodeGym

Multithreading : ce que font les méthodes de la classe Thread

Publié dans le groupe Random-FR
Salut! Aujourd'hui, nous allons continuer à parler de multithreading. Examinons la classe Thread et ce que font quelques-unes de ses méthodes. Lorsque nous avons étudié les méthodes de classe précédemment, nous écrivions généralement ceci : <nom de la méthode> -> <ce que fait la méthode>. Multithreading : ce que font les méthodes de la classe Thread - 1Cela ne fonctionnera pas avec Threadles méthodes de :) Elles ont une logique plus complexe que vous ne pourrez pas comprendre sans quelques exemples.

La méthode Thread.start()

Commençons par nous répéter. Comme vous vous en souvenez probablement, vous pouvez créer un thread en faisant en sorte que votre classe hérite de la Threadclasse et en remplaçant la run()méthode. Mais il ne démarre pas tout seul, bien sûr. Pour ce faire, nous appelons start()la méthode de notre objet. Multithreading : ce que font les méthodes de la classe Thread - 2Rappelons l'exemple de la leçon précédente :

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Thread executed: " + getName());
   }
}


public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Remarque : Pour démarrer un thread, vous devez appeler lastart()méthode spéciale plutôt que larun()méthode ! C'est une erreur facile à commettre, surtout lorsque vous commencez à étudier le multithreading. Dans notre exemple, si vous appelez larun()méthode 10 fois au lieu destart(), vous obtiendrez ceci :

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Regardez les résultats de notre programme : Thread exécuté : Thread-0 Thread exécuté : Thread-1 Thread exécuté : Thread-2 Thread exécuté : Thread-3 Thread exécuté : Thread-4 Thread exécuté : Thread-5 Thread exécuté : Thread-6 Thread exécuté : Thread-7 Thread exécuté : Thread-8 Thread exécuté : Thread-9 Regardez l'ordre de la sortie : Tout se passe dans un ordre parfait. Bizarre, hein ? Nous n'y sommes pas habitués, car nous savons déjà que l'ordre dans lequel les threads sont démarrés et exécutés est déterminé par un intellect supérieur à l'intérieur de notre système d'exploitation : le planificateur de threads. Peut-être qu'on a juste eu de la chance ? Bien sûr, ce n'est pas une question de chance. Vous pouvez le vérifier en exécutant le programme plusieurs fois. Le problème est qu'appeler lerun()La méthode directement n'a rien à voir avec le multithreading. Dans ce cas, le programme sera exécuté sur le thread principal, le même thread qui exécute la main()méthode. Il suffit d'imprimer successivement 10 lignes sur la console et le tour est joué. 10 discussions n'ont pas été lancées. Alors, souvenez-vous de cela à l'avenir et vérifiez-vous constamment. Si vous voulez que la run()méthode soit appelée, appelez start(). Allons plus loin.

La méthode Thread.sleep()

Pour suspendre l'exécution du thread en cours pendant un certain temps, nous utilisons la sleep()méthode . Multithreading : ce que font les méthodes de la classe Thread - 3La sleep()méthode prend un certain nombre de millisecondes comme argument, ce qui indique le temps nécessaire pour mettre le thread en veille.

public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - How long did I sleep? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " seconds");

   }
}
Sortie console : - Combien de temps ai-je dormi ? - 3 secondes Remarque : la sleep()méthode est statique : elle dort le thread en cours. C'est-à-dire celui en cours d'exécution. Voici un autre point important : un thread endormi peut être interrompu. Dans ce cas, le programme lance un InterruptedException. Nous allons considérer un exemple ci-dessous. Au fait, que se passe-t-il après le réveil du fil ? Continuera-t-il à être exécuté là où il s'est arrêté ? Non. Une fois qu'un thread s'est réveillé, c'est-à-dire que le temps passé en tant qu'argument à Thread.sleep()s'est écoulé, il passe en runnableÉtat. Mais cela ne signifie pas que le planificateur de threads l'exécutera. Il peut très bien donner la préférence à quelque autre fil non dormant et permettre à notre fil fraîchement réveillé de continuer son travail un peu plus tard. N'oubliez pas ceci : se réveiller ne veut pas dire continuer à travailler immédiatement !

La méthode Thread.join()

Multithreading : ce que font les méthodes de la classe Thread - 4La join()méthode suspend l'exécution du thread en cours jusqu'à ce qu'un autre thread se termine. Si nous avons 2 threads, t1et t2, et nous écrivons

t1.join()
puis t2ne commencera pas tant qu'il t1n'aura pas terminé son travail. La join()méthode peut être utilisée pour garantir l'ordre d'exécution des threads. Considérons le join()fonctionnement de la méthode dans l'exemple suivant :

public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Thread started: " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Thread " + getName() + " is finished.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /* The second thread (t2) will start running only after the first thread (t1)
       is finished (or an exception is thrown) */
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       // The main thread will continue running only after t1 and t2 have finished
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("All threads have finished. The program is finished.");

   }
}
Nous avons créé une ThreadExampleclasse simple. Sa tâche est d'afficher un message indiquant que le fil a commencé, de s'endormir pendant 5 secondes, puis de signaler enfin que le travail est terminé. Part de gâteau. La logique principale est dans la Mainclasse. Regardez les commentaires : nous utilisons la join()méthode pour gérer avec succès l'ordre d'exécution des threads. Si vous vous souvenez comment nous avons commencé ce sujet, l'ordre d'exécution est géré par le planificateur de threads. Il exécute les threads à sa propre discrétion : chaque fois d'une manière différente. Ici, nous utilisons la méthode pour garantir que le t1thread sera d'abord démarré et exécuté en premier, puis let2thread, et seulement après cela, le thread principal du programme continuera. Passons à autre chose. Dans les programmes réels, vous rencontrerez souvent des situations où vous devrez interrompre l'exécution d'un thread. Par exemple, notre thread est en cours d'exécution, mais il attend un certain événement ou une certaine condition. Si cela se produit, le thread s'arrête. Cela aurait probablement du sens s'il y avait une sorte de stop()méthode. Mais ce n'est pas si simple. Il était une fois, Java disposait d'une Thread.stop()méthode et permettait d'interrompre un thread. Mais il a ensuite été supprimé de la bibliothèque Java. Vous pouvez le trouver dans la documentation Oracle et voir qu'il est marqué comme obsolète. Pourquoi? Parce qu'il vient d'arrêter le fil sans rien faire d'autre. Par exemple, le thread peut travailler avec des données et changer quelque chose. Puis au milieu de son travail il fut brusquement et sans ménagement coupé par la stop()méthode. Sans un arrêt approprié, ni la libération de ressources, ni même la gestion des erreurs - il n'y avait rien de tout cela. Pour exagérer légèrement, la stop()méthode a simplement tout détruit sur son passage. C'était comme tirer le cordon d'alimentation de la prise pour éteindre l'ordinateur. Oui, vous pouvez obtenir le résultat souhaité. Mais tout le monde sait qu'après quelques semaines, l'ordinateur ne vous remerciera plus de le traiter de cette façon. C'est pourquoi la logique d'interruption des threads a changé en Java et utilise désormais une interrupt()méthode spéciale.

La méthode Thread.interrupt()

Que se passe-t-il si la interrupt()méthode est appelée sur un thread ? Il y a 2 possibilités :
  1. Si l'objet était dans l'état d'attente, par exemple, en raison des méthodes joinou sleep, l'attente sera interrompue et le programme lancera un InterruptedException.
  2. Si le thread était dans un état de fonctionnement, l' interruptedindicateur booléen sera défini sur l'objet.
Mais nous devons vérifier la valeur de ce drapeau sur l'objet et terminer correctement le travail par nous-mêmes ! C'est pourquoi la Threadclasse a la boolean isInterrupted()méthode. Revenons à l'exemple de l'horloge qui était dans une leçon du cours de base. Pour plus de commodité, nous l'avons légèrement simplifié :

public class Clock extends Thread {

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

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("The thread was interrupted");
               break;
           }
           System.out.println("Tick");
       }
   }
}
Dans ce cas, l'horloge est démarrée et commence à tourner toutes les secondes. A la 10ème seconde, on interrompt le fil de l'horloge. Comme vous le savez déjà, si le thread que nous essayons d'interrompre est dans l'un des états d'attente, le résultat est un InterruptedException. Il s'agit d'une exception vérifiée, nous pouvons donc facilement l'attraper et exécuter notre logique pour terminer le programme. Et c'est exactement ce que nous avons fait. Voici notre résultat : Tick Tick Tick Tcik Tick Tick Tick Tick Tick Le thread a été interrompu Ceci conclut notre introduction aux Threadméthodes les plus importantes de la classe. Bonne chance!
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION