Java Executor Framework
In this page:
What is the Executor Framework?
The Executor framework is a built-in concurrency library introduced in Java 5 that manages thread pools, task queues, and scheduling automatically. It removes the need to manually create, start, and track Thread objects yourself, which becomes error-prone once an application needs more than a handful of concurrent tasks.
Example: What is the Executor Framework?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(() -> System.out.println("Task managed by the pool"));
executor.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Single Thread Executor
A Single Thread Executor manages exactly one background worker thread and executes every submitted task sequentially, strictly in the order those tasks were submitted. This gives you the safety of single-threaded execution — no race conditions between tasks — while still keeping that work off the calling thread.
Example: Single Thread Executor
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("Task 1"));
executor.submit(() -> System.out.println("Task 2")); // runs after Task 1, same worker
executor.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Fixed Thread Pool
A Fixed Thread Pool manages a set number of worker threads and hands submitted tasks to whichever thread is free, reusing each thread across many tasks instead of spawning a new one every time. This bounds resource usage predictably, which matters a lot under heavy or bursty load.
Example: Fixed Thread Pool
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
int taskId = i;
executor.submit(() -> System.out.println("Task " + taskId));
}
executor.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Submitting Callable Tasks
Unlike the Runnable interface, the Callable interface represents tasks that can return a computed result and can throw checked exceptions during execution. Submitting a Callable to an executor gets you back a Future you can use to retrieve that result once the task finishes.
Example: Submitting Callable Tasks
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> 10 + 20;
Future<Integer> future = executor.submit(task);
System.out.println(future.get());
executor.shutdown();
}
}
Login to try C/C++/Java/PHP code in the editor
Shutting Down Executors
Always explicitly shut down executors you create, since their worker threads would otherwise keep the JVM alive indefinitely. Call shutdown() to stop accepting new tasks while letting already-submitted ones finish normally, or shutdownNow() when you need everything to stop immediately.
Example: Shutting Down Executors
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(() -> System.out.println("Task running"));
executor.shutdown(); // stop accepting new tasks, finish existing ones
}
}
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: