Multithreading dans Java
Toute application peut avoir plusieurs processus (instances). Chacun de ces processus peut être affecté soit à un seul thread, soit à plusieurs threads. Nous verrons dans ce tutoriel comment effectuer plusieurs tâches en même temps et en apprendrons également plus sur les threads et la synchronisation entre les threads.
Qu’est-ce qu’un fil unique ?
Un seul fil dans Java est fondamentalement une unité de traitement légère et la plus petite. Java utilise des threads en utilisant une « classe de thread ». Il existe deux types de threads : thread utilisateur et thread démon (les threads daemon 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émon.
Exemple de thread unique :
package demotest; public class GuruThread { public static void main(String[] args) { System.out.println("Single Thread"); } }
Avantages du fil unique :
- Réduit la surcharge de l'application car un seul thread s'exécute dans le système
- Cela réduit également le coût de maintenance de l’application.
Qu’est-ce que le multithreading Java?
multithreading in Java est un processus d'exécution simultanée de deux ou plusieurs threads 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 Concurrence dans Java. Chaque fil est parallèle les uns aux autres. Plusieurs threads n'attribuent pas de zone mémoire distincte, ils économisent donc de la mémoire. De plus, le changement de contexte entre les threads prend moins de temps.
Exemple de multithread :
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 parfois effectuer plusieurs opérations
- En tant que tels, 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 :
Il existe différentes étapes du cycle de vie du thread, comme le montre le diagramme ci-dessus :
- New
- Exécutable
- Fonctionnement
- Attendre
- 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éparts 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 start. Le contrôle du thread est donné au planificateur pour terminer l'exécution. Cela dépend du planificateur si le thread doit être exécuté.
- 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 commence à s'exécuter dans l'application.
- Attendre: C'est l'état dans lequel un thread doit attendre. Comme plusieurs threads sont en cours d’exécution dans l’application, une synchronisation entre les threads est nécessaire. Par conséquent, un thread doit attendre que l’autre thread soit exécuté. Par conséquent, cet état est appelé état d’attente.
- Morte: C'est l'état dans lequel le thread est terminé. Le thread est en cours d’exécution et dès qu’il a terminé le traitement, il est dans « l’état mort ».
Méthodes de multithreading dans Java
Certaines des méthodes couramment utilisées pour les threads sont :Method | Description |
---|---|
démarrer() | Cette méthode démarre l'exécution du thread et JVM appelle la méthode run() sur le thread. |
Sommeil (int millisecondes) | Cette méthode met le thread en veille, donc l'exécution du thread s'arrêtera pendant les 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 nouvelle priorité) | Cela change la priorité du thread. |
rendement () | Cela provoque l'arrêt du thread actuel et l'exécution d'autres threads. |
Mise en situation : Dans ce programme multithreading en Java Par exemple, 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 run 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 sous le nom « 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 va dormir pendant 1000 millisecondes.
- Codes 9-14 : Ici, nous avons placé 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 la 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 que 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.
Java Fil à coudre Synchronisation
En multithreading, les programmes ont un comportement asynchrone. 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 ou plusieurs threads, l'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 est utile 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 s'écrire sous la forme suivante :
Synchronized(object) { //Block of statements to be synchronized }
Multithreading dans Java Exemples de programmes
Dans ce multithreading Java Par exemple, nous prendrons deux threads et récupérerons les noms du thread.
Exemple1:
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, créons une instance nommée « guruThread1 » et créons un thread.
- Ligne de code 10 : Ici, nous instancions la classe Thread, créons une instance nommée « guruThread2 » et créons un thread.
- Ligne de code 11 : Nous commençons le fil de discussion, c'est-à-dire guruThread1.
- Ligne de code 12 : Nous commençons le fil de discussion, c'est-à-dire guruThread2.
- Ligne de code 13 : Afficher le texte sous la forme « Les noms des fils de discussion sont les suivants : »
- Ligne de code 14 : Obtenir le nom du thread 1 en utilisant la méthode getName() de la classe thread.
- Ligne de code 15 : Obtenir le nom du thread 2 en utilisant la méthode getName() de la classe thread.
Lorsque vous exécutez le code ci-dessus, vous obtenez le résultat suivant :
Sortie :
Les noms de threads sont affichés ici sous la forme
- Guru1
- Guru2
2 Exemple:
Dans ce multithreading dans Java Par exemple, nous allons apprendre à remplacer les méthodes run() et start() d'une interface exécutable, créer deux threads de cette classe et les exécuter en conséquence.
De plus, nous suivons deux cours,
- Celui qui implémentera l'interface exécutable et
- Un autre qui aura la méthode main 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) sous le nom de « threadguru1 » et nous démarrons le fil de discussion.
- 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) sous le nom de « threadguru2 » et nous démarrons le fil de discussion.
- 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 thread class et l’autre de type string.
- Ligne de code 15-18 : nous remplaçons le constructeur GuruThread3, qui prend un argument comme type de chaîne (qui est le nom du thread) qui est attribué à la variable de classe guruname et donc le nom du thread est stocké.
- Ligne de code 20 : Ici, nous remplaçons la méthode run() de l'interface exécutable.
- Ligne de code 21 : Nous générons 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émentons le compteur. Nous imprimons le nom du thread et le faisons également dormir 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 remplaçons la méthode de démarrage de l'interface exécutable.
- Ligne de code 35 : Nous affichons le texte « Thread démarré ».
- Ligne de code 36-40 : Ici, nous prenons une condition if pour vérifier si la variable de classe guruthread a de la valeur ou non. S'il est nul, nous créons une instance en utilisant une classe de thread qui prend le nom comme paramètre (dont la valeur a été attribuée dans le constructeur). Après quoi le thread est démarré à l’aide de la méthode start().
Lorsque vous exécutez le code ci-dessus, vous obtenez le résultat suivant :
Sortie:
Il y a deux fils de discussion, nous recevons donc deux fois le message « Thread démarré ».
Nous obtenons les noms des threads tels que nous les avons générés.
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 tutoriel, nous avons vu des applications multithread dans Java et comment utiliser un seul et plusieurs threads dans Java.
- Expliquer le multithreading dans Java:en 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,
- New
- Exécutable
- Fonctionnement
- Attendre
- Mort
- Nous avons également appris synchronisation entre les threads, ce qui aide l'application à fonctionner correctement.
- Programmation multithread dans Java facilite de nombreuses autres tâches d'application.