logo

Java Thread Pool

Java trådbasseng representerer en gruppe arbeidertråder som venter på jobben og gjenbrukes mange ganger.

Når det gjelder en trådpool, opprettes en gruppe tråder med fast størrelse. En tråd fra trådbasen trekkes ut og tildeles en jobb av tjenesteleverandøren. Etter at jobben er fullført, er tråden inne i trådbassenget igjen.

Trådbassengmetoder

newFixedThreadPool(int s): Metoden skaper en trådpool med den faste størrelsen s.

newCachedThreadPool(): Metoden oppretter en ny trådpool som oppretter de nye trådene ved behov, men vil fortsatt bruke den tidligere opprettede tråden når de er tilgjengelige for bruk.

hva betyr xdxd

newSingleThreadExecutor(): Metoden lager en ny tråd.

Fordel med Java Thread Pool

Bedre ytelse Det sparer tid fordi det ikke er nødvendig å opprette en ny tråd.

Sanntidsbruk

Den brukes i Servlet og JSP der containeren oppretter en trådpool for å behandle forespørselen.

Eksempel på Java Thread Pool

La oss se et enkelt eksempel på Java-trådpoolen som bruker ExecutorService og Executors.

Fil: 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(); } } } 

Fil: 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;>
last ned dette eksemplet

Eksempel på trådpool: 2

La oss se et annet eksempel på trådpoolen.

Filnavn: 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></=>

Forklaring: Det er tydelig ved å se på resultatet av programmet at oppgave 4 og 5 utføres kun når tråden har en inaktiv tråd. Frem til da er ekstraoppgavene satt i kø.

Takeaway fra eksemplet ovenfor er når man ønsker å utføre 50 oppgaver, men ikke er villig til å lage 50 tråder. I et slikt tilfelle kan man lage en pool med 10 tråder. Dermed blir 10 av 50 oppgaver tildelt, og resten settes i kø. Når en tråd av 10 tråder blir inaktiv, plukker den opp de 11thoppgave. De andre ventende oppgavene behandles på samme måte.

Risikoer involvert i trådpooler

Følgende er risikoen involvert i trådpoolene.

dødlås: Det er et kjent faktum at deadlock kan komme i ethvert program som involverer multithreading, og en trådpool introduserer et annet scenario med deadlock. Tenk på et scenario der alle trådene som kjører venter på resultatene fra trådene som er blokkert og venter i køen på grunn av at tråder ikke er tilgjengelige for kjøringen.

personell valgkommisjon betydning

Trådlekkasje: Lekkasje av tråder oppstår når en tråd fjernes fra bassenget for å utføre en oppgave, men ikke kommer tilbake til den etter at oppgaven er fullført. For eksempel, når en tråd kaster unntaket og bassengklassen ikke er i stand til å fange dette unntaket, går tråden ut og reduserer trådbassengstørrelsen med 1. Hvis det samme gjentar seg flere ganger, er det rimelige sjanser for at bassenget vil bli tomt, og derfor er det ingen tilgjengelige tråder i bassenget for å utføre andre forespørsler.

Ressurs-trening: Mye tid er bortkastet i kontekstbytte mellom tråder når størrelsen på trådpoolen er veldig stor. Når det er flere tråder enn det optimale antallet kan forårsake sultproblemet, og det fører til ressurstrenging.

Poeng å huske

Ikke still oppgavene som samtidig venter på resultatene fra de andre oppgavene i kø. Det kan føre til en fastlåst situasjon, som forklart ovenfor.

Forsiktighet må utvises når tråder brukes til operasjonen som er langvarig. Det kan føre til at tråden venter for alltid og vil til slutt føre til lekkasje av ressursen.

Til slutt må trådpoolen avsluttes eksplisitt. Hvis det ikke skjer, fortsetter programmet å kjøre, og det slutter aldri. Påkall shutdown()-metoden på trådpoolen for å avslutte eksekveren. Merk at hvis noen prøver å sende en annen oppgave til eksekveren etter avslutning, vil den kaste en RejectedExecutionException.

Man må forstå oppgavene for å effektivt justere trådbasen. Hvis de gitte oppgavene er kontrasterende, bør man se etter bassenger for å utføre ulike varianter av oppgaver slik at man kan justere dem riktig.

For å redusere sannsynligheten for å kjøre JVM tom for minne, kan man kontrollere de maksimale trådene som kan kjøres i JVM. Trådpoolen kan ikke opprette nye tråder etter at den har nådd maksimumsgrensen.

En trådpool kan bruke den samme brukte tråden hvis tråden er ferdig utført. Dermed spares tiden og ressursene som brukes til å opprette en ny tråd.

Tuning av trådbasen

Den nøyaktige størrelsen på en trådpool bestemmes av antall tilgjengelige prosessorer og typen oppgaver trådene må utføre. Hvis et system har P-prosessorene som bare har prosesser av beregningstype, vil den maksimale størrelsen på trådpoolen til P eller P + 1 oppnå maksimal effektivitet. Imidlertid kan oppgavene måtte vente på I/O, og i et slikt scenario må man ta hensyn til forholdet mellom ventetiden (W) og tjenestetiden (S) for forespørselen; resulterer i maksimal størrelse på bassenget P * (1 + W / S) for maksimal effektivitet.

Konklusjon

En trådpool er et veldig nyttig verktøy for å organisere applikasjoner, spesielt på serversiden. Konseptmessig er en trådpool veldig lett å forstå. Imidlertid kan det hende at man må se på mange problemer når man arbeider med en trådpool. Det er fordi trådpoolen kommer med noen risikoer involvert (risikoer er diskutert ovenfor).