Actualités>Tech news

Part 1. Introduction au multithreading en Java

18 juillet 2024Introduction au multithreading en java

Dans le monde de l'informatique, le multitâche fait référence à la capacité d'un ordinateur à gérer plusieurs tâches simultanément. Alors que les ordinateurs plus anciens ne pouvaient exécuter qu'une seule tâche à la fois, les processeurs modernes avec plusieurs cœurs et threads permettent un véritable multitâche.

Le multithreading est une technique de programmation qui permet à un seul programme d'exécuter plusieurs threads simultanément. Dans un contexte où les systèmes informatiques disposent de multiples cœurs de processeur, le multithreading permet d'exécuter plusieurs tâches en parallèle, optimisant ainsi l'utilisation des ressources et améliorant l'efficacité globale des programmes. Cette capacité à exécuter des tâches simultanément est cruciale pour une variété d'applications, allant des serveurs web traitant des milliers de requêtes simultanées aux interfaces utilisateur fluides et réactives. Dans cet article, nous parlerons du multithreading en Java, y compris ses avantages et inconvénients.

Créer un thread en Java

Java fournit des constructions intégrées pour la création et la gestion de threads. La principale façon de créer un thread est d'étendre la classe Thread ou d'implémenter l'interface Runnable.

La classe Thread

Constructeurs courants de la classe Thread :

  • Thread(): Ce constructeur crée un thread sans nom.

  • Thread(String name): Ce constructeur crée un thread avec un nom spécifié. Le nom peut être utile pour le débogage et la surveillance des threads.

  • Thread(Runnable r): Ce constructeur crée un thread qui exécute la tâche implémentée par l'objet Runnable fourni en argument.

  • Thread(Runnable r, String name): Ce constructeur combine les fonctionnalités des deux précédents, permettant de créer un thread avec un nom et une tâche spécifique à exécuter.

Méthodes courantes de la classe Thread en Java La classe Thread fournit des méthodes essentielles pour la gestion des threads. Voici une explication de certaines méthodes fréquemment utilisées :

  • public void run(): Cette méthode est le cœur de l'exécution d'un thread. C'est dans cette méthode que vous implémentez la logique ou la tâche que le thread doit exécuter.

  • public void start(): Cette méthode démarre l'exécution du thread. Lorsque vous appelez start(), la JVM (Java Virtual Machine) démarre un nouveau thread d'exécution et appelle la méthode run()sur ce nouveau thread.

  • public void sleep(long milliseconds): Cette méthode force le thread en cours d'exécution à se mettre en pause pendant un nombre spécifié de millisecondes. Le thread n'est pas terminé, il reprendra son exécution après le délai imparti.

  • public Thread currentThread(): Cette méthode renvoie la référence du thread en cours d'exécution. Elle est utile pour connaître le thread qui exécute actuellement un code spécifique.

  • public void yield(): Cette méthode permet au thread en cours d'exécution de céder temporairement le processeur à d'autres threads prêts à s'exécuter. Cela ne garantit pas l'exécution immédiate d'un autre thread, mais cela lui donne une chance de s'exécuter.

  • public void suspend()et public void resume(): Ces méthodes sont déconseillées car elles peuvent entraîner des problèmes de synchronisation des threads. Il est recommandé d'utiliser des approches alternatives pour la gestion de la suspension et de la reprise des threads.

  • public void stop(): Cette méthode est également déconseillée car elle peut interrompre brutalement le thread et entraîner des incohérences dans les données. Il est préférable d'utiliser des techniques d'interruption de thread plus contrôlées.

  • public boolean isDaemon(): Cette méthode permet de vérifier si le thread est un thread démon. Les threads démons s'arrêtent automatiquement lorsque tous les threads non-démon ont terminé leur exécution.

  • public void interrupt() et public boolean isInterrupted(): Ces méthodes permettent d'interrompre un thread. La méthode interrupt() signale au thread qu'il doit s'arrêter, tandis que isInterrupted() permet de vérifier si le thread a été interrompu.

  • public static boolean interrupted(): Cette méthode static vérifie si le thread en cours d'exécution a été interrompu.

Interface Runnable

L'interface Runnable est une pierre angulaire de la création et de l'exécution de threads en Java. Elle définit un contrat simple pour les tâches pouvant être exécutées par des threads. L'interface Runnable ne possède qu'une seule méthode abstraite : run(). C'est dans cette méthode que vous implémentez la logique ou la tâche que le thread doit exécuter.

La méthode run() ne prend aucun argument et ne renvoie aucune valeur.

Cet article t'as aidé ? Découvre maintenant comment gérer le cycle de vie d'un Thread

Créer un Thread avec la classe Thread

Explication : 

Le code donné montre comment créer et exécuter un thread en étendant la classe Thread en Java.

  1. Création de la Classe MyThread : - class MyThread extends Thread { ... } créer une nouvelle classe MyThread qui hérite de la classe Thread. - La méthode run() est surchargée pour définir le comportement du thread. Dans ce cas, elle imprime un message.

  2. Instanciation de MyThread : - MyThread thread = new MyThread(); crée une instance de la classe MyThread.

  3. Démarrage du Thread : - thread.start(); appelle la méthode start() de la classe Thread. - La méthode start() est responsable de créer un nouveau thread d'exécution et de l'initialiser. - Elle appelle ensuite la méthode run() de l'instance MyThread dans le nouveau thread.

Schéma de Fonctionnement

  • Avant start() : - Le thread n'est pas encore démarré. C'est simplement un objet MyThread.

  • Après start() : - Un nouveau thread d'exécution est créé. - La méthode run() de MyThread est exécutée dans ce nouveau thread. - La méthode run() imprime "Thread is running" sur la console.

Au final nous pouvons dire qu' en étendant la classe Thread et en surchargeant la méthode run(), nous définissons le comportement du thread. Lorsque la méthode start() est appelée, elle démarre un nouveau thread qui exécute le code défini dans la méthode run(). Dans cet exemple, le thread imprimera simplement un message indiquant qu'il est en cours d'exécution( "Thread is running").

Création d’un Thread avec l'Interface Runnable

Explication : 

Le code fourni indique comment créer et exécuter un thread en utilisant l'interface Runnable en Java.

  1. Création de la Classe MyRunnable : - class MyRunnable implements Runnable { ... } créer une nouvelle classe MyRunnable qui implémente l'interface Runnable. - La méthode run() est surchargée pour définir le comportement du thread. Dans ce cas, elle imprime un message.

  2. Instanciation de MyRunnable et Création du Thread : - new MyRunnable() crée une instance de la classe MyRunnable. - Thread thread = new Thread(new MyRunnable()); crée une instance de la classe Thread, en passant l'instance de MyRunnable comme argument au constructeur de Thread. - Ceci associe l'objet  MyRunnable avec le nouveau thread.

  3. Démarrage du Thread : - thread.start(); appelle la méthode start() de l'objet Thread. - La méthode start() est responsable de créer un nouveau thread d'exécution et de l'initialiser. - Elle appelle ensuite la méthode run() de l'objet MyRunnable associé dans le nouveau thread.

Schéma de Fonctionnement

  • Avant start() : - Le thread n'est pas encore démarré. C'est simplement un objet Thread associé à un objet MyRunnable.

  • Après start() : - Un nouveau thread d'exécution est créé. - La méthode run() de l'objet MyRunnable est exécutée dans ce nouveau thread. - La méthode run() imprime "Thread is running" sur la console.

Pourquoi utiliser Runnable ?

  • Séparation des Tâches : En utilisant Runnable, on sépare la définition de la tâche (ce que le thread doit faire) de la gestion du thread lui-même.

  • Réutilisation : Une même instance de Runnable peut être passée à plusieurs objets Thread si nécessaire.

  • Héritage : Si la classe doit hériter d'une autre classe (puisqu'en Java, une classe ne peut hériter que d'une seule classe), on peut implémenter Runnable plutôt que d'étendre Thread.

En utilisant l'interface Runnable, nous définissons la tâche à exécuter par le thread en implémentant la méthode run(). Ensuite, nous créons un thread en passant l'objet MyRunnable au constructeur de Thread. Enfin, nous démarrons le thread avec la méthode start(), qui exécute la méthode run() dans le nouveau thread. Ce modèle de programmation permet une séparation claire entre la logique de la tâche et la gestion du thread, rendant le code plus modulaire et réutilisable.

Cet article t'as aidé ? Découvre maintenant comment gérer le cycle de vie d’un thread !

Joel Tchoufa Nkouatchet
Joel Tchoufa Nkouatchet

Développeur Java Angular passionné par mon métier, j'aime contribuer à la communauté en partageant mes connaissances et en restant à l'affût des nouvelles technologies et meilleures pratiques.