Java Thread Pools
In this page:
Introduction to Thread Pools
Creating a brand-new thread for every task adds real memory and scheduling overhead, and doing that frequently under load can degrade an application's performance and even destabilize it. A thread pool solves this by maintaining a queue of reusable worker threads that tasks are handed off to, rather than spawning fresh threads on demand.
Example: Introduction to Thread Pools
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(() -> System.out.println("Reused worker thread runs this task"));
pool.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Cached Thread Pools
A cached thread pool dynamically resizes itself based on current load: it creates new threads as tasks arrive faster than existing threads can process them, and it retires threads that have sat idle for a while. This makes it well suited to workloads with many short-lived, bursty tasks.
Example: Cached Thread Pools
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 3; i++) {
pool.submit(() -> System.out.println("Short-lived task"));
}
pool.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Scheduled Thread Pools
A scheduled thread pool lets you schedule tasks to run once after a specified delay, or repeatedly at a fixed rate or fixed interval, without you having to manage timers yourself. This is the standard building block for background jobs like periodic cache refreshes or health checks.
Example: Scheduled Thread Pools
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.schedule(() -> System.out.println("Ran after delay"), 100, TimeUnit.MILLISECONDS);
Thread.sleep(200);
scheduler.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Single Thread Executor
A single-thread executor pool runs every submitted task sequentially on one dedicated background thread, guaranteeing tasks execute in the exact order they were submitted. This is useful whenever you need predictable, race-free ordering without paying for the complexity of explicit locking.
Example: Single Thread Executor
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.submit(() -> System.out.println("First"));
pool.submit(() -> System.out.println("Second")); // guaranteed to run after First
pool.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Shutting Down Thread Pools
Always shut down thread pools you create once they're no longer needed, since their live worker threads will otherwise keep the JVM running and leak resources indefinitely. Use shutdown() to let already-running tasks finish gracefully, or shutdownNow() to force an immediate stop.
Example: Shutting Down Thread Pools
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(() -> System.out.println("Task"));
pool.shutdown(); // lets running tasks finish
// pool.shutdownNow(); // would force an immediate stop instead
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: