4 méthodes pour écrire du code multi-thread en Java

  • Harry James
  • 0
  • 5086
  • 904
Publicité

Le multi-threading est une méthode d'écriture de code pour l'exécution de tâches en parallèle. Java bénéficie d'un excellent support pour l'écriture de code multi-thread depuis les débuts de Java 1.0. De récentes améliorations de Java ont permis de structurer le code de manière à incorporer le multi-threading dans les programmes Java..

Dans cet article, nous comparons quelques-unes de ces options afin que vous puissiez mieux déterminer quelle option utiliser pour votre prochain projet Java Love GitHub? 4 raisons pour lesquelles vous devriez héberger votre code sur BitBucket Love GitHub? 4 raisons pour lesquelles vous devriez héberger votre code sur BitBucket Vous devez penser à l'emplacement où vous souhaitez stocker votre code. Vous avez probablement entendu parler de GitHub. Ce n'est pas surprenant. GitHub est utilisé par les particuliers et les entreprises pour héberger du code, collaborer sur la documentation… t.

Méthode 1: extension de la classe Thread

Java fournit un Fil classe qui peut être étendue pour mettre en œuvre la courir() méthode. Cette méthode run () est l'endroit où vous implémentez votre tâche. Lorsque vous souhaitez lancer la tâche dans son propre thread, vous pouvez créer une instance de cette classe et appeler son début() méthode. Cela démarre l’exécution du thread et s’achève (ou se termine par une exception).

Voici une classe de thread simple qui ne dort que pendant un intervalle spécifié pour simuler une opération longue.

Classe publique MyThread s'étend à Thread private int sleepFor; public MyThread (int sleepFor) this.sleepFor = sleepFor;  @Override public void run () System.out.printf ("Un thread [% s] commençant par \ n", Thread.currentThread (). ToString ()); try Thread.sleep (this.sleepFor);  catch (InterruptedException ex)  System.out.printf ("Le thread [% s] se terminant par \ n", Thread.currentThread (). toString ());  

Créez une instance de cette classe Thread en lui donnant le nombre de millisecondes à attendre.

MyThread worker = new MyThread (sleepFor); 

Lancez l'exécution de ce thread de travail en appelant sa méthode start (). Cette méthode redonne immédiatement le contrôle à l'appelant, sans attendre la fin du thread..

worker.start (); System.out.printf ("[% s] thread principal \ n", Thread.currentThread (). ToString ()); 

Et voici le résultat de l'exécution de ce code. Il indique que le diagnostic du thread principal est imprimé avant que le thread de travail ne s'exécute..

[Filetage [principal, 5, principal]] filetage principal [Filetage [Filetage-0,5, principal]] filetage à partir [Filetage [Filetage-0,5, principal]] filetage final 

Comme il n'y a plus d'instructions après le démarrage du thread de travail, le thread principal attend que le thread de travail se termine avant la fin du programme. Cela permet au thread de travail de terminer sa tâche..

Méthode 2: à l'aide d'une instance de thread avec un exécutable

Java fournit également une interface appelée Runnable qui peut être implémenté par une classe de travailleurs pour exécuter la tâche dans son courir() méthode. C’est une autre façon de créer une classe de travailleurs plutôt que d’étendre la Fil classe (décrite ci-dessus).

Voici l'implémentation de la classe worker qui implémente maintenant Runnable au lieu d'étendre Thread.

La classe publique MyThread2 implémente Runnable // comme ci-dessus 

L'avantage d'implémenter l'interface Runnable au lieu d'étendre la classe Thread est que la classe de travail peut maintenant étendre une classe spécifique au domaine dans une hiérarchie de classes..

Qu'est-ce que ça veut dire?

Disons, par exemple, que vous avez un Fruit classe qui met en œuvre certaines caractéristiques génériques des fruits. Maintenant, vous voulez implémenter un Papaye classe qui spécialise certaines caractéristiques du fruit. Vous pouvez le faire en ayant le Papaye classe étendre la Fruit classe.

public class Fruit // spécificité du fruit ici public class Papaya étend Fruit // annule le comportement spécifique à la papaye ici 

Supposons maintenant que Papaya doive prendre en charge une tâche fastidieuse, qui peut être effectuée dans un thread séparé. Ce cas peut être traité en demandant à la classe Papaya d'implémenter Runnable et de fournir la méthode run () où cette tâche est effectuée..

public class Papaya réglementaire Fruit implémente Runnable // redéfinit le comportement spécifique à la papaye ici @Override public void run () // tâche fastidieuse ici.  

Pour lancer le thread de travail, créez une instance de la classe de travail et transmettez-la à une instance de Thread lors de sa création. Lorsque la méthode start () du thread est appelée, la tâche s'exécute dans un thread séparé..

Papaye Papaye = Papaye nouvelle (); // définit les propriétés et invoque les méthodes de papaye ici. Fil de discussion = nouveau fil (papaye); thread.start (); 

Et c'est un bref résumé de la façon d'utiliser un Runnable pour implémenter une tâche s'exécutant dans un thread.

Méthode 3: exécuter un exécutable avec ExecutorService

À partir de la version 1.5, Java fournit une ExecutorService comme nouveau paradigme pour la création et la gestion de threads dans un programme. Il généralise le concept d’exécution de threads en faisant abstraction de la création de threads.

En effet, vous pouvez exécuter vos tâches dans un pool de threads aussi facilement que si vous utilisiez un thread séparé pour chaque tâche. Cela permet à votre programme de suivre et de gérer le nombre de threads utilisés pour les tâches de travail..

Supposons que vous avez 100 tâches de travail en attente d'exécution. Si vous démarrez un thread par travailleur (comme présenté ci-dessus), vous aurez 100 threads dans votre programme, ce qui peut créer des goulots d'étranglement ailleurs dans le programme. Par contre, si vous utilisez un pool de threads avec, disons, 10 threads préalloués, vos 100 tâches seront exécutées par ces threads les uns après les autres, de sorte que votre programme ne manque pas de ressources. En outre, ces threads de pool de threads peuvent être configurés de manière à rester en place pour effectuer des tâches supplémentaires à votre place..

Un ExecutorService accepte un Runnable tâche (expliquée ci-dessus) et l'exécute au moment opportun. le soumettre() Cette méthode, qui accepte la tâche Runnable, renvoie une instance d’une classe appelée Futur, qui permet à l'appelant de suivre l'état de la tâche. En particulier, le obtenir() méthode permet à l'appelant d'attendre la fin de la tâche (et fournit le code de retour, le cas échéant).

Dans l'exemple ci-dessous, nous créons un ExecutorService en utilisant la méthode statique nouveauSingleThreadExecutor (), qui, comme son nom l'indique, crée un seul thread pour l'exécution de tâches. Si plusieurs tâches sont soumises alors qu'une tâche est en cours d'exécution, ExecutorService les place en file d'attente pour une exécution ultérieure..

L'implémentation Runnable que nous utilisons ici est la même que celle décrite ci-dessus.

ExecutorService esvc = Executors.newSingleThreadExecutor (); Runnable worker = new MyThread2 (sleepFor); Future future = esvc.submit (travailleur); System.out.printf ("[% s] thread principal \ n", Thread.currentThread (). ToString ()); future.get (); esvc.shutdown (); 

Notez qu'un service d'exécution doit être arrêté correctement lorsqu'il n'est plus nécessaire pour d'autres soumissions de tâches..

Méthode 4: un appelable utilisé avec ExecutorService

À partir de la version 1.5, Java a introduit une nouvelle interface appelée Appelable. Il est similaire à l’ancienne interface Runnable à la différence que la méthode d’exécution (appelée appel() au lieu de courir()) peut retourner une valeur. En outre, il peut également déclarer qu'un Exception peut être jeté.

Un ExecutorService peut également accepter des tâches implémentées en tant que Appelable et retourne un Futur avec la valeur renvoyée par la méthode à l'achèvement.

Voici un exemple Mangue classe qui étend la Fruit classe définie plus tôt et implémente la Appelable interface. Une tâche coûteuse et fastidieuse est effectuée dans le appel() méthode.

public class Mango s'étend Fruit implémente Callable public Integer call () // calcul coûteux, ici, retourne new Integer (0);  

Et voici le code pour soumettre une instance de la classe à un ExecutorService. Le code ci-dessous attend également que la tâche soit terminée et affiche sa valeur de retour..

ExecutorService esvc = Executors.newSingleThreadExecutor (); MyCallable worker = new MyCallable (sleepFor); Future future = esvc.submit (travailleur); System.out.printf ("[% s] thread principal \ n", Thread.currentThread (). ToString ()); System.out.println ("La tâche a renvoyé:" + future.get ()); esvc.shutdown (); 

Que préfères-tu?

Dans cet article, nous avons appris quelques méthodes pour écrire du code multithread en Java. Ceux-ci inclus:

  1. Étendre la Fil la classe est la plus basique et est disponible depuis Java 1.0.
  2. Si vous avez une classe qui doit étendre une autre classe dans une hiérarchie de classes, vous pouvez alors implémenter Runnable interface.
  3. Un outil plus moderne pour créer des threads est le ExecutorService qui peut accepter une instance Runnable en tant que tâche à exécuter. L'avantage de cette méthode est que vous pouvez utiliser un pool de threads pour l'exécution de tâches. Un pool de threads aide à la conservation des ressources en réutilisant les threads.
  4. Enfin, vous pouvez également créer une tâche en implémentant le Appelable interface et soumission de la tâche à un ExecutorService.

Laquelle de ces options pensez-vous utiliser dans votre prochain projet? Faites-nous savoir dans les commentaires ci-dessous.




Personne n'a encore commenté ce post.

De la technologie moderne, simple et abordable.
Votre guide dans le monde de la technologie moderne. Apprenez à utiliser les technologies et les gadgets qui nous entourent chaque jour et à découvrir des choses intéressantes sur Internet.