Når vi udvikler en multi-threaded applikation, skal vi normalt beskæftige os med at organisere arbejdet med tråde. Jo større vores applikation og jo flere tråde vi har brug for til flertrådede opgaver, jo flereKørbarobjekter vi skaber.

Det skal her bemærkes, at oprettelse af en tråd i Java er en ret dyr operation. Hvis vi opretter en ny forekomst af tråden hver gang for at udføre en operation, vil vi få store problemer med ydeevnen og som følge heraf med applikationens sundhed.

En trådpulje og ThreadPoolExecutor kommer os til hjælp her.

En trådpulje er et sæt præ-initialiserede tråde. Dens størrelse kan være fast eller variabel.

Hvis der er flere opgaver end tråde, så venter opgaver i en opgavekø. Den N'te tråd i puljen tager en opgave fra køen, og efter den er færdig, henter tråden en ny opgave fra køen. Når alle opgaver i køen er udført, forbliver trådene aktive og venter på nye opgaver. Når nye opgaver dukker op, begynder trådene også at udføre dem.

ThreadPoolExecutor

Startende med Java 5 fik Executor-rammeværket en multithreading-løsning. Generelt har den masser af komponenter, og dens formål er at hjælpe os med at administrere køer og trådpuljer effektivt.

De vigtigste grænseflader er Executor og ExecutorService .

Executor er en grænseflade med en enkelt void execute (Runnable runnable) metode.

Når du overfører en opgave til en implementering af denne metode, skal du vide, at den vil blive udført asynkront i fremtiden.

ExecutorService — En grænseflade, der udvider Executor- grænsefladen og tilføjer muligheder for at udføre opgaver. Det har også metoder til at afbryde en kørende opgave og afslutte trådpuljen.

ThreadPoolExecutor implementerer Executor- og ExecutorService- grænsefladerne og adskiller opgaveoprettelse fra opgaveudførelse. Vi er nødt til at implementere Kørbare objekter og sende dem til en eksekutør. ThreadPoolExecutorer derefter ansvarlig for at udføre opgaverne og oprette og arbejde med tråde .

Efter at en opgave er sendt til udførelse, bruges en eksisterende tråd i puljen. Dette forbedrer ydeevnen. Det løser problemet med at spilde ressourcer på at oprette og initialisere en ny tråd, og så igen på affaldsindsamling, når vi er færdige med tråden.

ThreadPoolExecutor har 4 konstruktører:


ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, 
RejectedExecutionHandler handler)
    

ThreadPoolExecutor - konstruktøren har følgende parametre:

corePoolSize Denne parameter angiver, hvor mange tråde der vil være klar (startet), når executor-tjenesten starter.
maximumPoolSize Det maksimale antal tråde, som en eksekveringstjeneste kan oprette.
keepAliveTime Den tid, en frigjort tråd vil fortsætte med at leve, før den bliver ødelagt, hvis antallet af tråde er større endcorePoolSize. Tidsenhederne angives i næste parameter.
enhed Tidsenheder (timer, minutter, sekunder, millisekunder osv.).
arbejdskø Implementering af kø til opgaver.
handler Behandler for opgaver, der ikke kan udføres.
trådfabrik Et objekt, der skaber nye tråde efter behov. Brug af trådfabrikker gør opkald til en ny trådhardware uafhængig, hvilket giver applikationer mulighed for at bruge specielle trådunderklasser, prioriteter og så videre.

Oprettelse af en ThreadPoolExecutor

Executors - hjælpeklassen kan forenkle oprettelsen af ​​en ThreadPoolExecutor . Metoderne i denne hjælpeklasse hjælper os med at forberede enThreadPoolExecutorobjekt.

newFixedThreadPool — Opretter en trådpulje, der genbruger et fast antal tråde til at udføre et vilkårligt antal opgaver.

ExecutorService executor = Executors.newFixedThreadPool(10);
                    
newWorkStealingPool — Opretter en trådpulje, hvor antallet af tråde er lig med antallet af processorkerner, der er tilgængelige for JVM. Standard samtidighedsniveauet er ét. Det betyder, at der vil blive oprettet lige så mange tråde i puljen, som der er CPU-kerner tilgængelige for JVM. Hvis samtidighedsniveauet er 4, bruges den beståede værdi i stedet for antallet af kerner.

ExecutorService executor = Executors.newWorkStealingPool(4);
                    
newSingleThreadExecutor — Opretter en pulje med en enkelt tråd til at udføre alle opgaver.

ExecutorService executor = Executors.newSingleThreadExecutor();
                    
newCachedThreadPool — Opretter en trådpulje, der opretter nye tråde efter behov, men genbruger tidligere oprettede tråde, når de er tilgængelige.

ExecutorService executor = Executors.newCachedThreadPool();
                    
newScheduledThreadPool — Opretter en trådpulje, der kan planlægge kommandoer til at udføre efter en given forsinkelse eller periodisk.

ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
                    

Vi vil overveje hver type pool i de følgende lektioner.