Careeroza
ExecutorService
Why Thread Pools
Creating a new platform thread for every task is expensive (about 1 MB stack, OS call). An ExecutorService keeps a pool of reusable threads and a queue of tasks.
submit(task) ─► ┌──────────────┐ ┌──────────┐
submit(task) ─► │ task queue │ ──► │ thread 1 │
submit(task) ─► └──────────────┘ ──► │ thread 2 │
──► │ thread 3 │
└──────────┘| Factory method | Pool |
|---|---|
Executors.newFixedThreadPool(n) | n threads, unbounded queue — CPU-bound work |
Executors.newCachedThreadPool() | grows as needed, idle threads die after 60 s |
Executors.newSingleThreadExecutor() | one thread, tasks run in order |
Executors.newScheduledThreadPool(n) | delayed and periodic tasks |
Executors.newVirtualThreadPerTaskExecutor() | Java 21: one virtual thread per task (I/O-bound) |
new ThreadPoolExecutor(core, max, keepAlive, unit, queue, handler) | full control (bounded queue, rejection policy) |
Submitting Tasks
Example
A single-thread executor runs tasks in submission order. ExecutorService is AutoCloseable since Java 19: try-with-resources calls close(), which waits for all tasks.
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
try (ExecutorService mailer = Executors.newSingleThreadExecutor()) {
for (String user : new String[]{"ravi", "anita", "john"}) {
mailer.submit(() -> System.out.println("Welcome mail sent to " + user));
}
} // close(): no new tasks, wait for queued tasks to finish
System.out.println("All mails sent");
}
}Output
Welcome mail sent to ravi Welcome mail sent to anita Welcome mail sent to john All mails sent
Shutting Down
| Method | Effect |
|---|---|
shutdown() | stop accepting tasks; queued tasks still run |
shutdownNow() | interrupt running tasks, return queued ones |
awaitTermination(t, unit) | block until finished or timeout |
close() (Java 19) | shutdown + wait; use with try-with-resources |
Note: A pool that is never shut down keeps the JVM alive (its threads are non-daemon). In Spring Boot, let the framework manage pools (ThreadPoolTaskExecutor bean, @Async).