Thread Pool in Java

Last Updated : 9 Apr, 2026

A Thread Pool is a collection of pre-created, reusable threads that are kept ready to perform tasks. Instead of creating a new thread every time you need to run something (which is costly in terms of memory and CPU), a thread pool maintains a fixed number of threads. When a task is submitted:

  • If a thread is free, it immediately picks up the task and runs it.
  • If all threads are busy, the task waits in a queue until a thread becomes available.
  • After finishing a task, the thread does not die. It goes back to the pool and waits for the next task.

Real World Analogy

Think of a call center:

  • A company has 10 operators (thread pool size = 10).
  • When customers call, available operators handle them.
  • If all operators are busy, new customers wait in a queue until someone is free.
  • Operators don’t leave after one call, they stay and handle more calls.

Benefits of Thread Pool

  • Better Performance: Threads are reused instead of being created and destroyed repeatedly.
  • Faster Response Time: Tasks don’t need to wait for a new thread to be created.
  • Reusability: Threads remain alive after finishing tasks and are reused for future tasks.
  • Resource Management: Limits the number of concurrent threads, preventing OutOfMemoryError or CPU overload.

Thread Pool Initialization

When we initialize a thread pool:

  • A fixed number of worker threads are created (e.g., 3).
  • These threads are kept idle, waiting for tasks.
  • A task queue is set up to hold submitted tasks until a worker is free.

Thread Pool Working

Here is the step by step working of thread pool.

Step 1: Idle State

  • Tasks are submitted and placed in the Task Queue.
  • Worker threads exist but are idle until work arrives.
Thread-Pool-1
Thread Pool Initialization with size = 3 threads. Task Queue = 5

Step 2: Task Assignment

  • Each idle thread picks a task from the queue.
  • Example: Thread 1 -> Task 1, Thread 2 -> Task 2, Thread 3 -> Task 3
  • Remaining tasks (Task 4, Task 5) wait in the queue.
Thread-Pool-2
Thread Pool executing first three tasks

Step 3: Thread Reuse

  • Once a thread completes its current task, it becomes idle again.
  • It immediately takes the next waiting task from the queue.
  • Example: Thread 1 -> Task 4, Thread 2 -> Task 5, Thread 3 -> Idle (no tasks left)
Thread-Pool-3
Thread Pool executing task 4 and 5

Code Example: Simple Thread Pool

Java
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

// Worker thread that executes tasks
class Worker extends Thread {
    private final BlockingQueue<Runnable> taskQueue;
    private static final Runnable POISON_PILL = () -> {};

    public Worker(BlockingQueue<Runnable> queue, String name) {
        super(name);
        this.taskQueue = queue;
    }

    public void run() {
        try {
            while (true) {
                Runnable task = taskQueue.take();

                if (task == POISON_PILL) {
                    break; // stop worker
                }

                try {
                    task.run();
                } catch (Exception e) {
                    System.out.println("Task error: " + e.getMessage());
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

// Thread Pool Implementation
class SimpleThreadPool {
    private final BlockingQueue<Runnable> taskQueue;
    private final Worker[] workers;
    private volatile boolean isShutdown = false;
    private static final Runnable POISON_PILL = () -> {};

    public SimpleThreadPool(int poolSize) {
        taskQueue = new LinkedBlockingQueue<>();
        workers = new Worker[poolSize];

        for (int i = 0; i < poolSize; i++) {
            workers[i] = new Worker(taskQueue, "Worker-" + (i + 1));
            workers[i].start();
        }
    }

    // Submit task
    public void submit(Runnable task) throws InterruptedException {
        if (!isShutdown) {
            taskQueue.put(task); // safer than offer()
        } else {
            throw new IllegalStateException("ThreadPool is shutdown");
        }
    }

    // Shutdown pool gracefully
    public void shutdown() {
        isShutdown = true;

        // Send stop signal to all workers
        for (int i = 0; i < workers.length; i++) {
            try {
                taskQueue.put(POISON_PILL);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        // Wait for workers to finish
        for (Worker worker : workers) {
            try {
                worker.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

// Test Program
public class ThreadPoolDemo {
    public static void main(String[] args) {
        SimpleThreadPool pool = new SimpleThreadPool(3);

        try {
            for (int i = 1; i <= 5; i++) {
                int taskId = i;

                pool.submit(() -> {
                    System.out.println("Executing Task " + taskId + " by " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        pool.shutdown();
        System.out.println("All tasks completed.");
    }
}

Output:

Screenshot-2025-08-19-115518
Output

Thread Pool methods

Here is the table of thread pool methods.

MethodPurpose
submit(Runnable task)Adds a task into the queue for execution by worker threads.
shutdown()Gracefully stops the thread pool → no new tasks accepted, workers stop after finishing current tasks.
shutdownNow() (optional)Immediately interrupts workers and clears pending tasks.
getQueueSize() (optional)Returns how many tasks are waiting in the queue.
getActiveCount() (optional)Returns number of threads currently executing tasks.
Comment