ExecutorService en typen threadpools
Maak vaste, gecachete, enkelvoudige en geplande threadpools en begrijp wanneer u elk type gebruikt.
ExecutorService en typen threadpools is een gratis Java Academy-les op CoddyKit. Dit is les 1 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.
Waarom threadpools gebruiken?
Voor elke taak een nieuwe Thread maken is duur — het maken en vernietigen van threads brengt extra kosten met zich mee. Een threadpool hergebruikt een vaste set threads om veel taken uit te voeren. Zo verlaag je de overhead en houd je het verbruik van bronnen onder controle.
import java.util.concurrent.*;
// Bad practice: new thread per task
new Thread(() -> System.out.println("task")).start();
// Better: reuse threads from a pool
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> System.out.println("task from pool"));
pool.shutdown();newFixedThreadPool
Maakt een pool met precies N threads. Extra taken komen in een wachtrij totdat er een thread beschikbaar is. Geschikt wanneer je het gewenste niveau van parallellisme kent.
ExecutorService pool = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
final int taskId = i;
pool.submit(() -> {
System.out.println("Task " + taskId + " on " + Thread.currentThread().getName());
});
}
pool.shutdown();
pool.awaitTermination(10, TimeUnit.SECONDS);newCachedThreadPool
Maakt threads wanneer dat nodig is en hergebruikt inactieve threads. Threads die 60 seconden inactief zijn, worden beëindigd. Geschikt voor veel kortdurende taken; riskant voor langlopende of onbeperkte taken, omdat het geheugen kan opraken.
ExecutorService cached = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
cached.submit(() -> {
// quick task
double result = Math.sqrt(Math.random());
});
}
cached.shutdown();newSingleThreadExecutor
Een pool met precies één thread. Taken worden achtereenvolgens uitgevoerd in de volgorde waarin ze zijn ingediend. Geschikt om toegang tot een gedeelde bron te serialiseren.
ExecutorService single = Executors.newSingleThreadExecutor();
single.submit(() -> System.out.println("Task 1"));
single.submit(() -> System.out.println("Task 2"));
single.submit(() -> System.out.println("Task 3"));
// Always prints: Task 1, Task 2, Task 3 (sequential)
single.shutdown();newScheduledThreadPool
Ondersteunt geplande en terugkerende taken. Gebruik deze voor polling, nieuwe pogingen en onderhoud op de achtergrond.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// One-shot delay
scheduler.schedule(() -> System.out.println("Delayed!"),
3, TimeUnit.SECONDS);
// Fixed rate (every 2 seconds)
scheduler.scheduleAtFixedRate(
() -> System.out.println("Tick"),
0, 2, TimeUnit.SECONDS);
// Run later: scheduler.shutdown();VirtualThreadExecutor (Java 21+)
Java 21 introduceert virtuele threads — lichtgewicht en goedkoop om te maken. Gebruik Executors.newVirtualThreadPerTaskExecutor() voor werklasten met veel I/O:
// Java 21+
try (var exec = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10_000; i++) {
final int id = i;
exec.submit(() -> {
Thread.sleep(100); // blocks without tying up OS thread
System.out.println("vthread " + id);
});
}
} // auto-shutdownDe juiste pool kiezen
Richtlijnen:
- CPU-gebonden taken: vaste pool met N = het aantal CPU-kernen
- I/O-gebonden taken: cachepool of virtuele threads
- Sequentiële taken: executor met één thread
- Geplande/terugkerende taken: geplande threadpool
int cores = Runtime.getRuntime().availableProcessors();
ExecutorService cpuPool = Executors.newFixedThreadPool(cores);
System.out.println("Pool size: " + cores);Aangepaste ThreadPoolExecutor
Maak voor fijnmazige controle rechtstreeks een ThreadPoolExecutor:
ThreadPoolExecutor tpe = new ThreadPoolExecutor(
2, // corePoolSize
10, // maximumPoolSize
60L, // keepAliveTime
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), // work queue
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy() // rejection policy
);
tpe.submit(() -> System.out.println("Custom pool task"));
tpe.shutdown();Gecontroleerd afsluiten
Sluit ExecutorService altijd af om threads vrij te geven. shutdown() accepteert geen nieuwe taken meer, maar voltooit taken die al in de wachtrij staan. shutdownNow() probeert actieve taken te annuleren.
ExecutorService pool = Executors.newFixedThreadPool(4);
// ... submit tasks ...
pool.shutdown(); // no new tasks
try {
if (!pool.awaitTermination(30, TimeUnit.SECONDS)) {
pool.shutdownNow(); // force cancel
}
} catch (InterruptedException e) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}ExecutorService als AutoCloseable (Java 19+)
In Java 19+ implementeert ExecutorService AutoCloseable. Gebruik try-with-resources voor automatisch afsluiten:
// Java 19+ (preview), Java 21 stable
try (ExecutorService pool = Executors.newFixedThreadPool(4)) {
pool.submit(() -> System.out.println("task"));
} // pool.close() called: waits for tasks then shuts downBeleid voor afwijzing
Wanneer de pool verzadigd is (alle threads zijn bezig en de wachtrij is vol), handelt het afwijzingsbeleid de overtollige taak af:
- AbortPolicy (standaard): werpt
RejectedExecutionException - CallerRunsPolicy: de aanroepende thread voert de taak uit
- DiscardPolicy: verwijdert de taak stilzwijgend
- DiscardOldestPolicy: verwijdert de oudste taak uit de wachtrij
Korte controle
Je hebt een CPU-gebonden taak die zware berekeningen uitvoert. Hoeveel threads moet je vaste threadpool hebben?
Samenvatting: ExecutorService en threadpools
Belangrijkste punten:
- Vaste pool: vast aantal N threads; extra taken komen in de wachtrij
- Cachepool: groeit wanneer dat nodig is; inactieve threads verlopen na 60 seconden
- Eén thread: de volgorde van sequentiële uitvoering is gegarandeerd
- Geplande pool: vertraagde en terugkerende taken
- Roep altijd
shutdown()aan; gebruikawaitTermination()voor netjes afsluiten
Leer Java met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 104
- Lessen
- 374
Veelgestelde vragen
Is de les “ExecutorService en typen threadpools” gratis?
Ja — de volledige tekst van “ExecutorService en typen threadpools” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.
Wat leer ik in “ExecutorService en typen threadpools”?
Maak vaste, gecachete, enkelvoudige en geplande threadpools en begrijp wanneer u elk type gebruikt. Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Java Academy te beginnen?
Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “ExecutorService en typen threadpools”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Java Academy?
Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- ExecutorService en typen threadpools
- Taken indienen: Runnable versus Callable
- Future en foutafhandeling
- ScheduledExecutorService voor terugkerende taken