Tutoriel multithreading en Java avec programme et exemples
Toute application peut avoir plusieurs processus (instances). Chacun de ces processus peut être affecté soit en tant que thread unique, soit en plusieurs threads. Nous allons voir dans ce tutoriel comment effectuer plusieurs tâches en même temps et aussi en savoir plus sur les threads et la synchronisation entre threads.
Dans ce tutoriel Multithreading en Java, nous allons apprendre :
- Qu'est-ce qu'un thread unique
- Qu'est-ce que le multithreading en Java ?
- Cycle de vie des threads en Java
- Synchronisation des threads Java
- Exemple de multithread Java
Qu'est-ce qu'un thread unique ?
Un seul thread en Java est fondamentalement un poids léger et la plus petite unité de traitement. Java utilise des threads en utilisant une "classe de thread".
Il existe deux types de thread :le thread utilisateur et le thread démon (les threads démons sont utilisés lorsque nous voulons nettoyer l'application et sont utilisés en arrière-plan).
Lorsqu'une application démarre pour la première fois, un thread utilisateur est créé. Après cela, nous pouvons créer de nombreux threads utilisateur et threads démons.
Exemple de thread unique :
package demotest; public class GuruThread { public static void main(String[] args) { System.out.println("Single Thread"); } }
Avantages du thread unique :
- Réduit les frais généraux de l'application car un seul thread s'exécute dans le système
- En outre, cela réduit les coûts de maintenance de l'application.
Qu'est-ce que le multithreading en Java ?
Multithreading en Java est un processus d'exécution simultanée de deux threads ou plus pour une utilisation maximale du processeur. Les applications multithread exécutent deux ou plusieurs threads exécutés simultanément. Par conséquent, il est également connu sous le nom de simultanéité en Java. Chaque fil est parallèle l'un à l'autre. Plusieurs threads n'allouent pas de zone de mémoire séparée, ils économisent donc de la mémoire. De plus, le changement de contexte entre les threads prend moins de temps.
Exemple de fil multi :
package demotest; public class GuruThread1 implements Runnable { public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
Avantages du multithread :
- Les utilisateurs ne sont pas bloqués car les threads sont indépendants et nous pouvons effectuer plusieurs opérations à la fois
- Ainsi, les threads sont indépendants, les autres threads ne seront pas affectés si un thread rencontre une exception.
Cycle de vie des threads en Java
Le cycle de vie d'un thread :

Cycle de vie des threads en Java
Il existe différentes étapes du cycle de vie du fil, comme indiqué dans le diagramme ci-dessus :
- Nouveau
- Exécutable
- Courir
- En attente
- Mort
- Nouveau : Dans cette phase, le thread est créé à l'aide de la classe "Thread class". Il reste dans cet état jusqu'à ce que le programme démarre le fil. Il est également connu sous le nom de fil né.
- Exécutable : Dans cette page, l'instance du thread est invoquée avec une méthode de démarrage. Le contrôle du thread est donné au planificateur pour terminer l'exécution. Cela dépend du planificateur, s'il faut exécuter le thread.
- En cours d'exécution : Lorsque le thread commence à s'exécuter, l'état passe à l'état "en cours d'exécution". Le planificateur sélectionne un thread dans le pool de threads et il commence à s'exécuter dans l'application.
- En attente : C'est l'état dans lequel un thread doit attendre. Comme plusieurs threads s'exécutent dans l'application, une synchronisation entre les threads est nécessaire. Par conséquent, un thread doit attendre jusqu'à ce que l'autre thread soit exécuté. Par conséquent, cet état est appelé état d'attente.
- Mort : C'est l'état lorsque le thread est terminé. Le thread est en cours d'exécution et dès qu'il a terminé le traitement, il est en "état mort".
Certaines des méthodes couramment utilisées pour les threads sont :
Méthode | Description |
---|---|
début() | Cette méthode démarre l'exécution du thread et JVM appelle la méthode run() sur le thread. |
Veille (int millisecondes) | Cette méthode met le thread en veille, donc l'exécution du thread s'arrêtera pendant quelques millisecondes fournies et après cela, le thread recommencera à s'exécuter. Cela aide à la synchronisation des threads. |
getName() | Il renvoie le nom du fil. |
setPriority(int nouvellepriorité) | Cela change la priorité du fil. |
rendement () | Il provoque l'arrêt du thread en cours et l'exécution d'autres threads. |
Exemple : Dans cet exemple de programme multithreading en Java, nous allons créer un thread et explorer les méthodes intégrées disponibles pour les threads.
package demotest; public class thread_example1 implements Runnable { @Override public void run() { } public static void main(String[] args) { Thread guruthread1 = new Thread(); guruthread1.start(); try { guruthread1.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } guruthread1.setPriority(1); int gurupriority = guruthread1.getPriority(); System.out.println(gurupriority); System.out.println("Thread Running"); } }
Explication du code :
- Ligne de code 2 : Nous créons une classe "thread_Example1" qui implémente l'interface Runnable (elle doit être implémentée par toute classe dont les instances sont destinées à être exécutées par le thread.)
- Ligne de code 4 : Il remplace la méthode d'exécution de l'interface exécutable car il est obligatoire de remplacer cette méthode
- Ligne de code 6 : Ici, nous avons défini la méthode principale dans laquelle nous allons démarrer l'exécution du thread.
- Ligne de code 7 : Ici, nous créons un nouveau nom de thread en tant que "guruthread1" en instanciant une nouvelle classe de thread.
- Ligne de code 8 : nous utiliserons la méthode "start" du thread en utilisant l'instance "guruthread1". Ici, le thread commencera à s'exécuter.
- Ligne de code 10 : Ici, nous utilisons la méthode "sleep" du thread en utilisant l'instance "guruthread1". Par conséquent, le thread dormira pendant 1 000 millisecondes.
- Code 9-14 : Ici, nous avons mis la méthode sleep dans le bloc try catch car il y a une exception vérifiée qui se produit, c'est-à-dire une exception interrompue.
- Ligne de code 15 : Ici, nous définissons la priorité du thread sur 1, quelle que soit sa priorité
- Ligne de code 16 : Ici, nous obtenons la priorité du thread en utilisant getPriority()
- Ligne de code 17 : Ici, nous imprimons la valeur extraite de getPriority
- Ligne de code 18 : Ici, nous écrivons un texte sur lequel le fil est en cours d'exécution.
Lorsque vous exécutez le code ci-dessus, vous obtenez le résultat suivant :
Sortie :
5 est la priorité du Thread, et Thread Running est le texte qui est la sortie de notre code.
Synchronisation des threads Java
En multithreading, il y a le comportement asynchrone des programmes. Si un thread écrit des données et qu'un autre thread lit des données en même temps, cela peut créer une incohérence dans l'application.
Lorsqu'il est nécessaire d'accéder aux ressources partagées par deux threads ou plus, une approche de synchronisation est utilisée.
Java a fourni des méthodes synchronisées pour implémenter un comportement synchronisé.
Dans cette approche, une fois que le thread atteint l'intérieur du bloc synchronisé, aucun autre thread ne peut appeler cette méthode sur le même objet. Tous les threads doivent attendre que ce thread termine le bloc synchronisé et en sorte.
De cette façon, la synchronisation aide dans une application multithread. Un thread doit attendre que l'autre thread termine son exécution, puis les autres threads sont autorisés à s'exécuter.
Il peut être écrit sous la forme suivante :
Synchronized(object) { //Block of statements to be synchronized }
Exemple de multithread Java
Dans cet exemple Java multithreading, nous allons prendre deux threads et récupérer les noms du thread.
Exemple 1 :
GuruThread1.java package demotest; public class GuruThread1 implements Runnable{ /** * @param args */ public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
Explication du code :
- Ligne de code 3 : Nous avons pris une classe "GuruThread1" qui implémente Runnable (elle doit être implémentée par toute classe dont les instances sont destinées à être exécutées par le thread.)
- Ligne de code 8 : C'est la méthode principale de la classe
- Ligne de code 9 : Ici, nous instancions la classe Thread et créons une instance nommée "guruThread1" et créons un thread.
- Ligne de code 10 : Ici, nous instancions la classe Thread et créons une instance nommée "guruThread2" et créons un thread.
- Ligne de code 11 : Nous démarrons le fil, c'est-à-dire guruThread1.
- Ligne de code 12 : Nous démarrons le fil, c'est-à-dire guruThread2.
- Ligne de code 13 : Afficher le texte sous la forme "Les noms de thread suivent :"
- Ligne de code 14 : Obtenir le nom du thread 1 à l'aide de la méthode getName() de la classe de thread.
- Ligne de code 15 : Obtenir le nom du thread 2 à l'aide de la méthode getName() de la classe de thread.
Lorsque vous exécutez le code ci-dessus, vous obtenez le résultat suivant :
Sortie :
Les noms de thread sont affichés ici sous la forme
- Guru1
- Guru2
Exemple 2 :
Dans cet exemple de multithreading en Java, nous allons apprendre à remplacer les méthodes run() et start() d'une interface exécutable et créer deux threads de cette classe et les exécuter en conséquence.
De plus, nous prenons deux cours,
- Celui qui implémentera l'interface exécutable et
- Un autre qui aura la méthode principale et s'exécutera en conséquence.
package demotest; public class GuruThread2 { public static void main(String[] args) { // TODO Auto-generated method stub GuruThread3 threadguru1 = new GuruThread3("guru1"); threadguru1.start(); GuruThread3 threadguru2 = new GuruThread3("guru2"); threadguru2.start(); } } class GuruThread3 implements Runnable { Thread guruthread; private String guruname; GuruThread3(String name) { guruname = name; } @Override public void run() { System.out.println("Thread running" + guruname); for (int i = 0; i < 4; i++) { System.out.println(i); System.out.println(guruname); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Thread has been interrupted"); } } } public void start() { System.out.println("Thread started"); if (guruthread == null) { guruthread = new Thread(this, guruname); guruthread.start(); } } }
Explication du code :
- Ligne de code 2 : Ici, nous prenons une classe "GuruThread2" qui contiendra la méthode principale.
- Ligne de code 4 : Ici, nous prenons une méthode principale de la classe.
- Ligne de code 6-7 : Ici, nous créons une instance de la classe GuruThread3 (qui est créée dans les lignes ci-dessous du code) en tant que "threadguru1" et nous démarrons le thread.
- Ligne de code 8-9 : Ici, nous créons une autre instance de la classe GuruThread3 (qui est créée dans les lignes ci-dessous du code) en tant que "threadguru2" et nous démarrons le thread.
- Ligne de code 11 : Ici, nous créons une classe "GuruThread3" qui implémente l'interface exécutable (elle doit être implémentée par toute classe dont les instances sont destinées à être exécutées par le thread.)
- Ligne de code 13-14 : nous prenons deux variables de classe dont l'une est de type classe thread et l'autre de classe chaîne.
- Ligne de code 15-18 : nous remplaçons le constructeur GuruThread3, qui prend un argument comme type de chaîne (qui est le nom des threads) qui est assigné à la variable de classe guruname et donc le nom du thread est stocké.
- Ligne de code 20 : Ici, nous redéfinissons la méthode run() de l'interface exécutable.
- Ligne de code 21 : Nous produisons le nom du thread à l'aide de l'instruction println.
- Ligne de code 22-31 : Ici, nous utilisons une boucle for avec un compteur initialisé à 0, et il ne doit pas être inférieur à 4 (nous pouvons prendre n'importe quel nombre, donc ici la boucle s'exécutera 4 fois) et incrémenter le compteur. Nous imprimons le nom du thread et faisons également dormir le thread pendant 1000 millisecondes dans un bloc try-catch car la méthode sleep a déclenché une exception vérifiée.
- Ligne de code 33 : Ici, nous redéfinissons la méthode de démarrage de l'interface exécutable.
- Ligne de code 35 : Nous affichons le texte "Thread started".
- Ligne de code 36-40 : Ici, nous prenons une condition if pour vérifier si la variable de classe guruthread a une valeur ou non. S'il est nul, nous créons une instance à l'aide de la classe de thread qui prend le nom comme paramètre (la valeur pour laquelle a été attribuée dans le constructeur). Après quoi le thread est démarré en utilisant la méthode start().
Lorsque vous exécutez le code ci-dessus, vous obtenez le résultat suivant :
Sortie :
Il y a deux threads donc, nous recevons deux fois le message "Thread started".
Nous obtenons les noms du fil tels que nous les avons sortis.
Il entre dans la boucle for où nous imprimons le compteur et le nom du thread et le compteur commence par 0.
La boucle s'exécute trois fois et entre les deux, le thread est mis en veille pendant 1000 millisecondes.
Par conséquent, d'abord, nous obtenons guru1 puis guru2 puis à nouveau guru2 parce que le thread dort ici pendant 1000 millisecondes, puis ensuite guru1 et encore guru1, le thread dort pendant 1000 millisecondes, donc nous obtenons guru2 puis guru1.
Résumé
Dans ce didacticiel, nous avons vu des applications multithreads en Java et comment utiliser un seul et plusieurs threads en Java.
- Expliquez le multithreading en Java :dans le multithreading, les utilisateurs ne sont pas bloqués car les threads sont indépendants et peuvent effectuer plusieurs opérations à la fois
- Les différentes étapes du cycle de vie du fil sont,
- Nouveau
- Exécutable
- Courir
- En attente
- Mort
- Nous avons également découvert la synchronisation entre les threads, qui permet à l'application de fonctionner correctement.
- La programmation multithread en Java facilite de nombreuses autres tâches d'application.
Java
- Programme Java Hello World
- Fonctions C++ avec exemples de programmes
- Tutoriel sur les collections C # avec des exemples
- Méthode Java String indexOf() avec sous-chaîne et exemples
- Méthode Java String charAt() avec exemple
- Méthode Java String compareTo () :comment utiliser des exemples
- Surcharge de constructeurs en Java :Qu'est-ce que c'est et exemples de programmes
- Programme Java pour vérifier le nombre premier
- Algorithme de tri par insertion en Java avec exemple de programme