Bij het ontwikkelen van een toepassing met meerdere threads hebben we meestal te maken met het organiseren van het werk van threads. Hoe groter onze applicatie en hoe meer threads we nodig hebben voor multithreaded taken, hoe meerUitvoerbaarobjecten die we maken.

Hierbij moet worden opgemerkt dat het maken van een thread in Java een vrij dure operatie is. Als we elke keer een nieuwe instantie van de thread maken om een ​​bewerking uit te voeren, krijgen we grote problemen met de prestaties en als gevolg daarvan met de gezondheid van de applicatie.

Een threadpool en ThreadPoolExecutor komen ons hier te hulp.

Een threadpool is een set vooraf geïnitialiseerde threads. De grootte kan vast of variabel zijn.

Als er meer taken dan threads zijn, wachten taken in een taakwachtrij. De N-th thread in de pool neemt een taak uit de wachtrij en nadat deze is voltooid, pikt de thread een nieuwe taak uit de wachtrij op. Zodra alle taken in de wachtrij zijn uitgevoerd, blijven de threads actief en wachten ze op nieuwe taken. Wanneer er nieuwe taken verschijnen, beginnen de threads deze ook uit te voeren.

ThreadPoolExecutor

Vanaf Java 5 kreeg het Executor-framework een multithreading-oplossing. Over het algemeen heeft het veel componenten en het doel ervan is om ons te helpen wachtrijen en threadpools efficiënt te beheren.

De belangrijkste interfaces zijn Executor en ExecutorService .

Executor is een interface met een enkele void execute (Runnable runnable) methode.

Wanneer u een taak doorgeeft aan een implementatie van deze methode, weet dan dat deze in de toekomst asynchroon zal worden uitgevoerd.

ExecutorService — Een interface die de Executor- interface uitbreidt en mogelijkheden toevoegt voor het uitvoeren van taken. Het heeft ook methoden om een ​​lopende taak te onderbreken en de threadpool te beëindigen.

ThreadPoolExecutor implementeert de interfaces Executor en ExecutorService en scheidt het maken van taken van het uitvoeren van taken. We moeten Runnable- objecten implementeren en naar een uitvoerder sturen. De ThreadPoolExecutor is dan verantwoordelijk voor het uitvoeren van de taken en het maken van en werken met threads.

Nadat een taak is verzonden voor uitvoering, wordt een bestaande thread in de pool gebruikt. Dit verbetert de prestaties. Het lost het probleem op van het verspillen van bronnen aan het maken en initialiseren van een nieuwe thread, en vervolgens weer aan het verzamelen van afval zodra we klaar zijn met de thread.

ThreadPoolExecutor heeft 4 constructors:


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)
    

De ThreadPoolExecutor- constructor heeft de volgende parameters:

corePoolSize Deze parameter geeft aan hoeveel threads klaar (gestart) zullen zijn wanneer de executor-service start.
maximalePoolSize Het maximum aantal threads dat een uitvoerende service kan maken.
houdAliveTime De tijd dat een bevrijde thread blijft leven voordat hij wordt vernietigd als het aantal threads groter is dancorePoolSize. De tijdseenheden worden gespecificeerd in de volgende parameter.
eenheid Tijdseenheden (uren, minuten, seconden, milliseconden, enz.).
werkwachtrij Implementatie van een wachtrij voor taken.
behandelaar Handler voor taken die niet kunnen worden voltooid.
draadfabriek Een object dat op verzoek nieuwe threads maakt. Het gebruik van thread factory's maakt oproepen naar een nieuwe thread hardware-onafhankelijk, waardoor applicaties speciale thread-subklassen, prioriteiten, enzovoort kunnen gebruiken.

Een ThreadPoolExecutor maken

De hulpprogrammaklasse Executors kan het maken van een ThreadPoolExecutor vereenvoudigen . De methoden van deze hulpprogrammaklasse helpen ons bij het voorbereiden van eenThreadPoolExecutorvoorwerp.

newFixedThreadPool — Creëert een threadpool die een vast aantal threads hergebruikt om een ​​willekeurig aantal taken uit te voeren.

ExecutorService executor = Executors.newFixedThreadPool(10);
                    
newWorkStealingPool — Creëert een threadpool waarbij het aantal threads gelijk is aan het aantal processorcores dat beschikbaar is voor de JVM. Het standaard gelijktijdigheidsniveau is één. Dit betekent dat er evenveel threads in de pool worden gemaakt als er CPU-cores beschikbaar zijn voor de JVM. Als het gelijktijdigheidsniveau 4 is, wordt de doorgegeven waarde gebruikt in plaats van het aantal cores.

ExecutorService executor = Executors.newWorkStealingPool(4);
                    
newSingleThreadExecutor — Creëert een pool met een enkele thread om alle taken uit te voeren.

ExecutorService executor = Executors.newSingleThreadExecutor();
                    
newCachedThreadPool — Creëert een threadpool die indien nodig nieuwe threads maakt, maar eerder gemaakte threads hergebruikt wanneer ze beschikbaar zijn.

ExecutorService executor = Executors.newCachedThreadPool();
                    
newScheduledThreadPool - Creëert een threadpool die opdrachten kan plannen om na een bepaalde vertraging of periodiek uit te voeren.

ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
                    

In de volgende lessen zullen we elk type zwembad bespreken.