Java ExecutorService: Thread Pools, Callable, Future & Concurrency

Introduced in Java 5 inside java.util.concurrent, the Executor Framework abstracts away the low-level complexities of managing raw thread lifecycles by introducing high-performance Thread Pools.

Using ExecutorService & Callable<V>

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;

public class ExecutorServiceDemo {
    public static void main(String[] args) throws Exception {
        // Create a fixed thread pool with 3 worker threads
        ExecutorService executor = Executors.newFixedThreadPool(3);

        // Submit a Callable task that returns a computed result
        Callable<Integer> calculation = () -> {
            System.out.println("Processing complex calculation on " + Thread.currentThread().getName());
            Thread.sleep(1000);
            return 42 * 10;
        };

        // Submit returns a Future holding the asynchronous result
        Future<Integer> futureResult = executor.submit(calculation);

        System.out.println("Main thread continues doing other work...");
        
        // .get() blocks until the worker thread produces the result:
        Integer result = futureResult.get();
        System.out.println("Calculation Result: " + result); // 420

        // Always shutdown executors cleanly!
        executor.shutdown();
    }
}

Next Step

Java 21 introduced the biggest concurrency leap in 25 years: Virtual Threads (Project Loom). Proceed to: Java 21 Virtual Threads →

Frequently Asked Questions (FAQ)

Q1. Why should we use Thread Pools instead of manually creating Thread objects?
Creating an OS thread incurs significant CPU and memory overhead (~1 MB stack allocation). Thread pools maintain a pool of reusable worker threads, preventing thread creation churn, out-of-memory crashes, and CPU thrashing under high traffic loads.
Q2. What is the difference between Runnable and Callable in Java?
Runnable has a void run() method that cannot return a result and cannot throw checked exceptions. Callable has a V call() method that can return a computed result and can throw checked exceptions.
Q3. What is a Future object in Java concurrency?
A Future represents the pending result of an asynchronous computation. It provides methods like get() (blocks until computation completes) and isDone() (checks completion status).

Explore Related Java Tutorials

Accelerate your Java mastery by studying these tightly connected core tutorials:

Java 21 Virtual Threads →

The future of Java concurrency.

Multithreading Basics →

Thread fundamentals.

Lambda Expressions →

Submitting tasks via lambdas.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!