1. Introduction
L'utilisation rationnelle des pools de threads peut apporter trois avantages. Premièrement: réduire la consommation de ressources. Réduisez la consommation causée par la création et la destruction des threads en réutilisant les fils créés. Deuxièmement: améliorez la vitesse de réponse. Lorsqu'une tâche arrive, la tâche peut être exécutée immédiatement après la création du thread. Troisièmement: améliorer la gestion des threads. Les threads sont des ressources rares. S'ils sont créés de manière illimité, ils consommeront non seulement les ressources du système, mais réduiront également la stabilité du système. L'utilisation de pools de threads peut être une allocation, un réglage et une surveillance unifiés. Cependant, pour utiliser rationnel des pools de fil, vous devez bien connaître ses principes.
2. Utilisation de la piscine de fil
Les quatre types de threads fournis par les exécuteurs 1.NewCachedThreadpool crée un pool de threads cacheable. Si la longueur du pool de filetage dépasse les besoins de traitement, il peut recycler flexiblement les threads inactifs. S'il n'y a pas de recyclage, créez un nouveau fil. 2.NewFixEdThreadpool crée un pool de threads de longueur fixe qui peut contrôler le nombre maximum de threads concurrencés, et les threads excédentaires attendront dans la file d'attente. 3.NewScheDuleDThreadPool crée un pool de threads de longueur fixe qui prend en charge l'exécution de tâches chronométrée et périodique. 4.NewSingLetHreAdExecutor crée un pool de threads unique, qui n'utilisera qu'un thread de travailleur unique pour exécuter des tâches, en veillant à ce que toutes les tâches soient exécutées dans l'ordre spécifié (FIFO, LIFO, priorité).
1.NewcachedThreadpool crée une piscine de fil cacheable. Si la longueur du pool de filetage dépasse les besoins de traitement, il peut recycler flexiblement les threads inactifs. S'il n'y a pas de recyclage, créez un nouveau fil. L'exemple est le suivant
ExecutorService ExecutorService = exécutor.NewCachedThreadPool (); pour (int i = 0; i <5; i ++) {final int index = i; essayez {thread.sleep (index * 1000); } catch (InterruptedException e) {e.printStackTrace (); } EMMICRORSERVICE.Execute (new Runnable () {@Override public void run () {System.out.println (Thread.currentThread (). GetName () + "," + index);}});} // Pool-1-thread-1,0pool-1-thread-1,1pool-1-thread-1,2pool-1-thread-1,3pool-1-thread-1,42.NewFixEdThreadpool crée un pool de threads de longueur fixe qui peut contrôler le nombre maximum de threads concurrencés, et les threads excédentaires attendront dans la file d'attente. L'exemple est le suivant
ExecutorService fixeThreadpool = exécutor.NewFixEdThreadPool (4); for (int i = 0; i <5; i ++) {final int index = i; FixedThreadpool.Execute (new Runnable () {@Override public void run () {try {System.out.println (thread.currentThread (). GetName () + "," + index); Pool-1-thread-1,0pool-1-thread-2,1pool-1-thread-3,2pool-1-thread-4,3pool-1-thread-1,43.NewScheduledThreadpool Créez un pool de threads de longueur fixe, et les exemples de cycles de support et de tâches de synchronisation sont les suivants
ScheduleDExECUTORService scheduledThreadpool = exécutors.newScheduledThreadPool (5); System.out.println ("avant:" + System.CurrentTimeMillis () / 1000); ScheduledThreadpool.schedule (new Runnable () {@Override public void run () {System.out.println ("EXÉCUTION DÉLÉVÉE pendant 3 secondes:" + System.Currenttimemillis () + System.Currenttimemillis () / 1000); // Informations sur la console avant: 1518012703After: 1518012703 retardée de 3 secondes: 1518012706System.out.println ("avant:" + System.CurrenttimeMillis () / 1000); ?Message console
Avant: 1518013024
Après: 1518013024
Après 1 seconde de retard, exécutez une fois en 3 secondes: 1518013025
Après 1 seconde de retard, exécutez une fois en 3 secondes: 1518013028
Après 1 seconde de retard, exécutez une fois en 3 secondes: 1518013031
4.NewSingLetHreAdExecutor crée un pool de threads unique, qui utilise uniquement des threads de travail pour exécuter des tâches, assurant l'ordre. L'exemple est le suivant
ExecutorService singleThreAdExEcutor = exécutor.NewSingLethreAdExecutor (); for (int i = 0; i <10; i ++) {final int index = i; SingleThreAdExecutor.Execute (new Runnable () {@Override public void run () {try {System.out.println (thread.currentThread (). getName () + "," + index);Informations sur la console
Pool-1-thread-1,0
piscine-1-thread-1,1
piscine-1-thread-1,2
piscine-1-thread-1,3
Pool-1-thread-1,4
Soumettez des tâches au pool de fil. La différence entre EXECUTE () et Soumide () dans la classe ThreadPoolExecutor est en fait une méthode déclarée dans l'exécuteur exécuteur. Il est implémenté dans ThreadPoolExecutor. Cette méthode est la méthode principale de ThreadPoolExecutor. Grâce à cette méthode, une tâche peut être soumise au pool de threads et remise au pool de threads pour exécution.
La méthode Soumide () est une méthode déclarée dans l'exécutor-service. Il a été mis en œuvre dans l'abstractExecutorService. Il n'est pas réécrit dans le threadpoolExecutor. Cette méthode est également utilisée pour soumettre des tâches au pool de threads. Cependant, il est différent de la méthode Execute (). Il peut renvoyer le résultat de l'exécution de la tâche. Vérifiez la mise en œuvre de la méthode Soumide () via le code source et vous constaterez qu'il s'agit en fait de la méthode exécutée () appelée, mais il utilise Future pour obtenir le résultat d'exécution de la tâche.
/ ** * @throws rejectEdExecutionException {@InheritDoc} * @throws nullpointerException {@inheritDoc} * / public future <?> soumid (runnable task) {if (task == null) lance un nouveau nullpointerException (); Runnablefuture <void> ftask = newtaskfor (tâche, null); exécuter (ftask); retour ftask;}Close of Thread Pool Nous pouvons fermer le pool de threads en appelant la méthode de fermeture ou de fermeture du pool de threads, mais leurs principes d'implémentation sont différents. Le principe de l'arrêt est de simplement définir l'état du pool de threads sur l'état d'arrêt, puis d'interrompre tous les threads qui ne font pas d'exécution de tâches. Le principe de Shutdownnow est de traverser les fils de travail dans le pool de threads, puis d'appeler la méthode d'interruption du fil un par un pour interrompre le fil, de sorte que les tâches qui ne peuvent pas répondre aux interruptions peuvent ne jamais être terminées. ShutdownNow définira d'abord l'état du pool de threads pour s'arrêter, puis essaie d'arrêter tous les threads qui exécutent ou pauses des tâches, et revenez à la liste des tâches d'attente.
Tant que l'une de ces deux méthodes de clôture est appelée, la méthode IsShutdown renvoie vrai. Lorsque toutes les tâches ont été fermées, cela signifie que le pool de fils est fermé avec succès. L'appel de la méthode iSTermina rendra vrai. Quant à quelle méthode nous devons appeler pour fermer le pool de threads, il doit être déterminé par les caractéristiques de la tâche soumises au pool de threads. Habituellement, l'arrêt est appelé pour fermer le pool de fils. Si la tâche n'a pas à être exécutée, ShutdownNow peut être appelé.
3. Analyse du pool de threads
Analyse du processus: Le flux de travail principal du pool de threads est illustré dans la figure ci-dessous: le flux de travail principal du pool de threads Java
D'après la figure ci-dessus, nous pouvons voir que lors de la soumission d'une nouvelle tâche au pool de threads, le flux de traitement du pool de threads est le suivant:
** Analyse du code source. ** L'analyse de processus ci-dessus nous permet de comprendre intuitivement le principe de travail des pools de fil. Utilisons le code source pour voir comment il est implémenté. Le pool de threads exécute des tâches comme suit:
public void execute (Runnable Command) {if (Command == null) lance un nouveau nullpointerException (); int c = ctl.get (); if (workerCountOf (c) <corePoolSize) {if (addWorker (commande, true)) return; c = ctl.get (); } if (Isrunning (c) && workQueue.offer (Command)) {int reheck = ctl.get (); if (! Isrunning (reCheck) && retire (Command)) rejeter (Command); else if (workerCountOf (reCheck) == 0) addWorker (null, false); } else if (! addWorker (commande, false)) rejeter (commande);} Fil de travail. Lorsqu'un pool de threads crée un fil, il encapsule le fil dans un fil de travail. Une fois que le travailleur a exécuté la tâche, il bouclera également à l'infini pour obtenir des tâches dans la file d'attente de travail à exécuter.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.