logo

Pool de threads Java

Pool de threads Java représente un groupe de threads de travail qui attendent le travail et réutilisés plusieurs fois.

Dans le cas d'un pool de threads, un groupe de threads de taille fixe est créé. Un thread du pool de threads est extrait et une tâche lui est attribuée par le fournisseur de services. Une fois le travail terminé, le thread est à nouveau contenu dans le pool de threads.

sinon si java

Méthodes du pool de threads

newFixedThreadPool(ints): La méthode crée un pool de threads de taille fixe.

nouveauCachedThreadPool() : La méthode crée un nouveau pool de threads qui crée les nouveaux threads en cas de besoin, mais utilisera toujours le thread créé précédemment chaque fois qu'ils seront disponibles.

newSingleThreadExecutor() : La méthode crée un nouveau fil de discussion.

Avantage du pool de threads Java

Meilleure performance Cela fait gagner du temps car il n’est pas nécessaire de créer un nouveau fil de discussion.

Utilisation en temps réel

Il est utilisé dans Servlet et JSP où le conteneur crée un pool de threads pour traiter la demande.

Exemple de pool de threads Java

Voyons un exemple simple du pool de threads Java utilisant ExecutorService et Executors.

Fichier : WorkerThread.java

 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class WorkerThread implements Runnable { private String message; public WorkerThread(String s){ this.message=s; } public void run() { System.out.println(Thread.currentThread().getName()+' (Start) message = '+message); processmessage();//call processmessage method that sleeps the thread for 2 seconds System.out.println(Thread.currentThread().getName()+' (End)');//prints thread name } private void processmessage() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } 

Fichier : TestThreadPool.java

 public class TestThreadPool { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads for (int i = 0; i <10; i++) { runnable worker="new" workerthread('' + i); executor.execute(worker); calling execute method of executorservice } executor.shutdown(); while (!executor.isterminated()) system.out.println('finished all threads'); < pre> <p> <strong>Output:</strong> </p> <pre>pool-1-thread-1 (Start) message = 0 pool-1-thread-2 (Start) message = 1 pool-1-thread-3 (Start) message = 2 pool-1-thread-5 (Start) message = 4 pool-1-thread-4 (Start) message = 3 pool-1-thread-2 (End) pool-1-thread-2 (Start) message = 5 pool-1-thread-1 (End) pool-1-thread-1 (Start) message = 6 pool-1-thread-3 (End) pool-1-thread-3 (Start) message = 7 pool-1-thread-4 (End) pool-1-thread-4 (Start) message = 8 pool-1-thread-5 (End) pool-1-thread-5 (Start) message = 9 pool-1-thread-2 (End) pool-1-thread-1 (End) pool-1-thread-4 (End) pool-1-thread-3 (End) pool-1-thread-5 (End) Finished all threads </pre> download this example <h2>Thread Pool Example: 2</h2> <p>Let&apos;s see another example of the thread pool.</p> <p> <strong>FileName:</strong> ThreadPoolExample.java</p> <pre> // important import statements import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.text.SimpleDateFormat; class Tasks implements Runnable { private String taskName; // constructor of the class Tasks public Tasks(String str) { // initializing the field taskName taskName = str; } // Printing the task name and then sleeps for 1 sec // The complete process is getting repeated five times public void run() { try { for (int j = 0; j <= 5; j++) { if (j="=" 0) date dt="new" date(); simpledateformat sdf="new" simpledateformat('hh : mm ss'); prints the initialization time for every task system.out.println('initialization name: '+ taskname + '=" + sdf.format(dt)); } else { Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat(" hh execution system.out.println('time of is complete.'); } catch(interruptedexception ie) ie.printstacktrace(); public class threadpoolexample maximum number threads in thread pool static final int max_th="3;" main method void main(string argvs[]) creating five new tasks runnable rb1="new" tasks('task 1'); rb2="new" 2'); rb3="new" 3'); rb4="new" 4'); rb5="new" 5'); a with size fixed executorservice pl="Executors.newFixedThreadPool(MAX_TH);" passes objects to execute (step 3) pl.execute(rb1); pl.execute(rb2); pl.execute(rb3); pl.execute(rb4); pl.execute(rb5); shutdown pl.shutdown(); < pre> <p> <strong>Output:</strong> </p> <pre> Initialization time for the task name: task 1 = 06 : 13 : 02 Initialization time for the task name: task 2 = 06 : 13 : 02 Initialization time for the task name: task 3 = 06 : 13 : 02 Time of execution for the task name: task 1 = 06 : 13 : 04 Time of execution for the task name: task 2 = 06 : 13 : 04 Time of execution for the task name: task 3 = 06 : 13 : 04 Time of execution for the task name: task 1 = 06 : 13 : 05 Time of execution for the task name: task 2 = 06 : 13 : 05 Time of execution for the task name: task 3 = 06 : 13 : 05 Time of execution for the task name: task 1 = 06 : 13 : 06 Time of execution for the task name: task 2 = 06 : 13 : 06 Time of execution for the task name: task 3 = 06 : 13 : 06 Time of execution for the task name: task 1 = 06 : 13 : 07 Time of execution for the task name: task 2 = 06 : 13 : 07 Time of execution for the task name: task 3 = 06 : 13 : 07 Time of execution for the task name: task 1 = 06 : 13 : 08 Time of execution for the task name: task 2 = 06 : 13 : 08 Time of execution for the task name: task 3 = 06 : 13 : 08 task 2 is complete. Initialization time for the task name: task 4 = 06 : 13 : 09 task 1 is complete. Initialization time for the task name: task 5 = 06 : 13 : 09 task 3 is complete. Time of execution for the task name: task 4 = 06 : 13 : 10 Time of execution for the task name: task 5 = 06 : 13 : 10 Time of execution for the task name: task 4 = 06 : 13 : 11 Time of execution for the task name: task 5 = 06 : 13 : 11 Time of execution for the task name: task 4 = 06 : 13 : 12 Time of execution for the task name: task 5 = 06 : 13 : 12 Time of execution for the task name: task 4 = 06 : 13 : 13 Time of execution for the task name: task 5 = 06 : 13 : 13 Time of execution for the task name: task 4 = 06 : 13 : 14 Time of execution for the task name: task 5 = 06 : 13 : 14 task 4 is complete. task 5 is complete. </pre> <p> <strong>Explanation:</strong> It is evident by looking at the output of the program that tasks 4 and 5 are executed only when the thread has an idle thread. Until then, the extra tasks are put in the queue.</p> <p>The takeaway from the above example is when one wants to execute 50 tasks but is not willing to create 50 threads. In such a case, one can create a pool of 10 threads. Thus, 10 out of 50 tasks are assigned, and the rest are put in the queue. Whenever any thread out of 10 threads becomes idle, it picks up the 11<sup>th </sup>task. The other pending tasks are treated the same way.</p> <h2>Risks involved in Thread Pools</h2> <p>The following are the risk involved in the thread pools.</p> <p> <strong>Deadlock:</strong> It is a known fact that deadlock can come in any program that involves multithreading, and a thread pool introduces another scenario of deadlock. Consider a scenario where all the threads that are executing are waiting for the results from the threads that are blocked and waiting in the queue because of the non-availability of threads for the execution.</p> <p> <strong>Thread Leakage:</strong> Leakage of threads occurs when a thread is being removed from the pool to execute a task but is not returning to it after the completion of the task. For example, when a thread throws the exception and the pool class is not able to catch this exception, then the thread exits and reduces the thread pool size by 1. If the same thing repeats a number of times, then there are fair chances that the pool will become empty, and hence, there are no threads available in the pool for executing other requests.</p> <p> <strong>Resource Thrashing:</strong> A lot of time is wasted in context switching among threads when the size of the thread pool is very large. Whenever there are more threads than the optimal number may cause the starvation problem, and it leads to resource thrashing.</p> <h2>Points to Remember</h2> <p>Do not queue the tasks that are concurrently waiting for the results obtained from the other tasks. It may lead to a deadlock situation, as explained above.</p> <p>Care must be taken whenever threads are used for the operation that is long-lived. It may result in the waiting of thread forever and will finally lead to the leakage of the resource.</p> <p>In the end, the thread pool has to be ended explicitly. If it does not happen, then the program continues to execute, and it never ends. Invoke the shutdown() method on the thread pool to terminate the executor. Note that if someone tries to send another task to the executor after shutdown, it will throw a RejectedExecutionException.</p> <p>One needs to understand the tasks to effectively tune the thread pool. If the given tasks are contrasting, then one should look for pools for executing different varieties of tasks so that one can properly tune them.</p> <p>To reduce the probability of running JVM out of memory, one can control the maximum threads that can run in JVM. The thread pool cannot create new threads after it has reached the maximum limit.</p> <p>A thread pool can use the same used thread if the thread has finished its execution. Thus, the time and resources used for the creation of a new thread are saved.</p> <h2>Tuning the Thread Pool</h2> <p>The accurate size of a thread pool is decided by the number of available processors and the type of tasks the threads have to execute. If a system has the P processors that have only got the computation type processes, then the maximum size of the thread pool of P or P + 1 achieves the maximum efficiency. However, the tasks may have to wait for I/O, and in such a scenario, one has to take into consideration the ratio of the waiting time (W) and the service time (S) for the request; resulting in the maximum size of the pool P * (1 + W / S) for the maximum efficiency.</p> <h2>Conclusion</h2> <p>A thread pool is a very handy tool for organizing applications, especially on the server-side. Concept-wise, a thread pool is very easy to comprehend. However, one may have to look at a lot of issues when dealing with a thread pool. It is because the thread pool comes with some risks involved it (risks are discussed above).</p> <hr></=></pre></10;>
téléchargez cet exemple

Exemple de pool de threads : 2

Voyons un autre exemple de pool de threads.

Nom de fichier: ThreadPoolExample.java

 // important import statements import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.text.SimpleDateFormat; class Tasks implements Runnable { private String taskName; // constructor of the class Tasks public Tasks(String str) { // initializing the field taskName taskName = str; } // Printing the task name and then sleeps for 1 sec // The complete process is getting repeated five times public void run() { try { for (int j = 0; j <= 5; j++) { if (j="=" 0) date dt="new" date(); simpledateformat sdf="new" simpledateformat(\'hh : mm ss\'); prints the initialization time for every task system.out.println(\'initialization name: \'+ taskname + \'=" + sdf.format(dt)); } else { Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat(" hh execution system.out.println(\'time of is complete.\'); } catch(interruptedexception ie) ie.printstacktrace(); public class threadpoolexample maximum number threads in thread pool static final int max_th="3;" main method void main(string argvs[]) creating five new tasks runnable rb1="new" tasks(\'task 1\'); rb2="new" 2\'); rb3="new" 3\'); rb4="new" 4\'); rb5="new" 5\'); a with size fixed executorservice pl="Executors.newFixedThreadPool(MAX_TH);" passes objects to execute (step 3) pl.execute(rb1); pl.execute(rb2); pl.execute(rb3); pl.execute(rb4); pl.execute(rb5); shutdown pl.shutdown(); < pre> <p> <strong>Output:</strong> </p> <pre> Initialization time for the task name: task 1 = 06 : 13 : 02 Initialization time for the task name: task 2 = 06 : 13 : 02 Initialization time for the task name: task 3 = 06 : 13 : 02 Time of execution for the task name: task 1 = 06 : 13 : 04 Time of execution for the task name: task 2 = 06 : 13 : 04 Time of execution for the task name: task 3 = 06 : 13 : 04 Time of execution for the task name: task 1 = 06 : 13 : 05 Time of execution for the task name: task 2 = 06 : 13 : 05 Time of execution for the task name: task 3 = 06 : 13 : 05 Time of execution for the task name: task 1 = 06 : 13 : 06 Time of execution for the task name: task 2 = 06 : 13 : 06 Time of execution for the task name: task 3 = 06 : 13 : 06 Time of execution for the task name: task 1 = 06 : 13 : 07 Time of execution for the task name: task 2 = 06 : 13 : 07 Time of execution for the task name: task 3 = 06 : 13 : 07 Time of execution for the task name: task 1 = 06 : 13 : 08 Time of execution for the task name: task 2 = 06 : 13 : 08 Time of execution for the task name: task 3 = 06 : 13 : 08 task 2 is complete. Initialization time for the task name: task 4 = 06 : 13 : 09 task 1 is complete. Initialization time for the task name: task 5 = 06 : 13 : 09 task 3 is complete. Time of execution for the task name: task 4 = 06 : 13 : 10 Time of execution for the task name: task 5 = 06 : 13 : 10 Time of execution for the task name: task 4 = 06 : 13 : 11 Time of execution for the task name: task 5 = 06 : 13 : 11 Time of execution for the task name: task 4 = 06 : 13 : 12 Time of execution for the task name: task 5 = 06 : 13 : 12 Time of execution for the task name: task 4 = 06 : 13 : 13 Time of execution for the task name: task 5 = 06 : 13 : 13 Time of execution for the task name: task 4 = 06 : 13 : 14 Time of execution for the task name: task 5 = 06 : 13 : 14 task 4 is complete. task 5 is complete. </pre> <p> <strong>Explanation:</strong> It is evident by looking at the output of the program that tasks 4 and 5 are executed only when the thread has an idle thread. Until then, the extra tasks are put in the queue.</p> <p>The takeaway from the above example is when one wants to execute 50 tasks but is not willing to create 50 threads. In such a case, one can create a pool of 10 threads. Thus, 10 out of 50 tasks are assigned, and the rest are put in the queue. Whenever any thread out of 10 threads becomes idle, it picks up the 11<sup>th </sup>task. The other pending tasks are treated the same way.</p> <h2>Risks involved in Thread Pools</h2> <p>The following are the risk involved in the thread pools.</p> <p> <strong>Deadlock:</strong> It is a known fact that deadlock can come in any program that involves multithreading, and a thread pool introduces another scenario of deadlock. Consider a scenario where all the threads that are executing are waiting for the results from the threads that are blocked and waiting in the queue because of the non-availability of threads for the execution.</p> <p> <strong>Thread Leakage:</strong> Leakage of threads occurs when a thread is being removed from the pool to execute a task but is not returning to it after the completion of the task. For example, when a thread throws the exception and the pool class is not able to catch this exception, then the thread exits and reduces the thread pool size by 1. If the same thing repeats a number of times, then there are fair chances that the pool will become empty, and hence, there are no threads available in the pool for executing other requests.</p> <p> <strong>Resource Thrashing:</strong> A lot of time is wasted in context switching among threads when the size of the thread pool is very large. Whenever there are more threads than the optimal number may cause the starvation problem, and it leads to resource thrashing.</p> <h2>Points to Remember</h2> <p>Do not queue the tasks that are concurrently waiting for the results obtained from the other tasks. It may lead to a deadlock situation, as explained above.</p> <p>Care must be taken whenever threads are used for the operation that is long-lived. It may result in the waiting of thread forever and will finally lead to the leakage of the resource.</p> <p>In the end, the thread pool has to be ended explicitly. If it does not happen, then the program continues to execute, and it never ends. Invoke the shutdown() method on the thread pool to terminate the executor. Note that if someone tries to send another task to the executor after shutdown, it will throw a RejectedExecutionException.</p> <p>One needs to understand the tasks to effectively tune the thread pool. If the given tasks are contrasting, then one should look for pools for executing different varieties of tasks so that one can properly tune them.</p> <p>To reduce the probability of running JVM out of memory, one can control the maximum threads that can run in JVM. The thread pool cannot create new threads after it has reached the maximum limit.</p> <p>A thread pool can use the same used thread if the thread has finished its execution. Thus, the time and resources used for the creation of a new thread are saved.</p> <h2>Tuning the Thread Pool</h2> <p>The accurate size of a thread pool is decided by the number of available processors and the type of tasks the threads have to execute. If a system has the P processors that have only got the computation type processes, then the maximum size of the thread pool of P or P + 1 achieves the maximum efficiency. However, the tasks may have to wait for I/O, and in such a scenario, one has to take into consideration the ratio of the waiting time (W) and the service time (S) for the request; resulting in the maximum size of the pool P * (1 + W / S) for the maximum efficiency.</p> <h2>Conclusion</h2> <p>A thread pool is a very handy tool for organizing applications, especially on the server-side. Concept-wise, a thread pool is very easy to comprehend. However, one may have to look at a lot of issues when dealing with a thread pool. It is because the thread pool comes with some risks involved it (risks are discussed above).</p> <hr></=>

Explication: Il est évident en regardant la sortie du programme que les tâches 4 et 5 ne sont exécutées que lorsque le thread a un thread inactif. En attendant, les tâches supplémentaires sont mises dans la file d'attente.

multiplexeur deux à un

Ce qu’il faut retenir de l’exemple ci-dessus, c’est lorsque l’on souhaite exécuter 50 tâches mais n’est pas disposé à créer 50 threads. Dans un tel cas, on peut créer un pool de 10 threads. Ainsi, 10 tâches sur 50 sont attribuées et le reste est mis en file d'attente. Chaque fois qu'un thread sur 10 devient inactif, il récupère le 11èmetâche. Les autres tâches en attente sont traitées de la même manière.

Risques impliqués dans les pools de threads

Voici les risques impliqués dans les pools de threads.

Impasse: C'est un fait connu qu'un blocage peut survenir dans n'importe quel programme impliquant le multithreading, et un pool de threads introduit un autre scénario de blocage. Considérons un scénario dans lequel tous les threads en cours d'exécution attendent les résultats des threads bloqués et en attente dans la file d'attente en raison de la non-disponibilité des threads pour l'exécution.

Fuite de fil : Une fuite de threads se produit lorsqu'un thread est supprimé du pool pour exécuter une tâche mais n'y revient pas une fois la tâche terminée. Par exemple, lorsqu'un thread lève l'exception et que la classe pool n'est pas en mesure d'intercepter cette exception, le thread se termine et réduit la taille du pool de threads de 1. Si la même chose se répète plusieurs fois, il y a de bonnes chances que le pool deviendra vide et, par conséquent, aucun thread n'est disponible dans le pool pour exécuter d'autres requêtes.

Dévastation des ressources : Beaucoup de temps est perdu à changer de contexte entre les threads lorsque la taille du pool de threads est très grande. Chaque fois qu'il y a plus de threads que le nombre optimal, cela peut provoquer un problème de famine et entraîner une épuisement des ressources.

Points à retenir

Ne mettez pas en file d'attente les tâches qui attendent simultanément les résultats obtenus des autres tâches. Cela peut conduire à une situation de blocage, comme expliqué ci-dessus.

Des précautions doivent être prises chaque fois que des threads sont utilisés pour une opération de longue durée. Cela peut entraîner une attente interminable du thread et finalement conduire à une fuite de la ressource.

En fin de compte, le pool de threads doit être terminé explicitement. Si cela ne se produit pas, le programme continue de s’exécuter et ne se termine jamais. Invoquez la méthode shutdown() sur le pool de threads pour mettre fin à l'exécuteur. Notez que si quelqu'un essaie d'envoyer une autre tâche à l'exécuteur après l'arrêt, il lancera une RejectedExecutionException.

Il faut comprendre les tâches pour régler efficacement le pool de threads. Si les tâches données sont contrastées, il convient alors de rechercher des pools pour exécuter différentes variétés de tâches afin de pouvoir les ajuster correctement.

Pour réduire la probabilité d'exécuter la JVM à court de mémoire, on peut contrôler le nombre maximum de threads pouvant s'exécuter dans la JVM. Le pool de threads ne peut pas créer de nouveaux threads une fois qu'il a atteint la limite maximale.

Un pool de threads peut utiliser le même thread utilisé si le thread a terminé son exécution. Ainsi, le temps et les ressources utilisés pour la création d'un nouveau fil sont économisés.

qu'est-ce que le hashset java

Réglage du pool de threads

La taille précise d'un pool de threads dépend du nombre de processeurs disponibles et du type de tâches que les threads doivent exécuter. Si un système dispose de processeurs P qui n'ont que les processus de type calcul, alors la taille maximale du pool de threads de P ou P + 1 atteint l'efficacité maximale. Cependant, les tâches peuvent devoir attendre les E/S, et dans un tel scénario, il faut prendre en considération le rapport entre le temps d'attente (W) et le temps de service (S) pour la requête ; résultant en la taille maximale de la piscine P* (1 + W/S) pour une efficacité maximale.

Conclusion

Un pool de threads est un outil très pratique pour organiser les applications, notamment côté serveur. D'un point de vue conceptuel, un pool de threads est très facile à comprendre. Cependant, il faudra peut-être examiner de nombreux problèmes lorsqu’il s’agit d’un pool de threads. C’est parce que le pool de threads comporte certains risques (les risques sont discutés ci-dessus).