Thread Pool in JavaLast Updated : 16 Jan 2026 Thread pools are used to manage and reuse multiple threads while executing concurrent tasks. In this chapter, we will learn how thread pools work and how they improve performance in Java applications. What is Thread Pool in Java?Thread pool is a group of already created threads that are reused to perform multiple tasks. The thread pool is managed by the JVM. Instead of creating a new thread for every task, tasks are given to the thread pool, and available threads execute them. Thread pool improves performance, reduces the cost of creating threads, and manages system resource. There are the following three conditions when a task is submitted:
Simple Real-Life ExampleA thread pool can be understood by thinking about a restaurant kitchen. The kitchen has a fixed number of chefs who are always available to work. Each food order is treated as a task, and any free chef prepares the order. If all chefs are busy, new orders wait until a chef becomes available. The chefs do not leave after completing one order; instead, they continue working on the next orders. In the same way, a thread pool reuses threads to handle multiple tasks efficiently. How a Thread Pool Works?The following are the three main steps involved in the working of a thread pool: Step 1: Waiting StateWhen tasks are submitted, they are placed in a task queue. The thread pool is created with a fixed number of worker threads, which remain idle and wait for tasks to arrive. Step 2: Task ExecutionEach available thread picks one task from the queue and starts executing it. If all threads are busy, the remaining tasks stay in the queue until a thread becomes free. Step 3: Thread ReuseAfter a thread completes its task, it does not terminate. Instead, it becomes available again and immediately takes the next task from the queue. If no tasks are left, the thread stays idle and waits for new tasks. Advantages of Thread PoolThe following are some of the main advantages of thread pool:
Examples of Thread PoolThe following examples demonstrate how thread pools manage and execute multiple tasks efficiently. Example 1: Fixed Thread Pool Using ExecutorServiceThe following example demonstrates how a fixed-size thread pool executes multiple tasks by reusing a limited number of threads. File Name: Main.java Output: pool-1-thread-1 (Start) message = 0 pool-1-thread-2 (Start) message = 1 pool-1-thread-3 (Start) message = 2 pool-1-thread-5 (Start) message = 4 pool-1-thread-4 (Start) message = 3 pool-1-thread-2 (End) pool-1-thread-2 (Start) message = 5 pool-1-thread-1 (End) pool-1-thread-1 (Start) message = 6 pool-1-thread-3 (End) pool-1-thread-3 (Start) message = 7 pool-1-thread-4 (End) pool-1-thread-4 (Start) message = 8 pool-1-thread-5 (End) pool-1-thread-5 (Start) message = 9 pool-1-thread-2 (End) pool-1-thread-1 (End) pool-1-thread-4 (End) pool-1-thread-3 (End) pool-1-thread-5 (End) Finished all threads Example 2: Executing Multiple Tasks with Thread PoolThe following example demonstrates how a thread pool handles multiple tasks using a fixed number of threads and executes them in batches. Output: Initialization time for the task name: task 1 = 12 : 14 : 02 Initialization time for the task name: task 3 = 12 : 14 : 02 Initialization time for the task name: task 2 = 12 : 14 : 02 Time of execution for the task name: task 1 = 12 : 14 : 04 Time of execution for the task name: task 3 = 12 : 14 : 04 Time of execution for the task name: task 2 = 12 : 14 : 04 Time of execution for the task name: task 1 = 12 : 14 : 05 Time of execution for the task name: task 3 = 12 : 14 : 05 Time of execution for the task name: task 2 = 12 : 14 : 05 Time of execution for the task name: task 1 = 12 : 14 : 06 Time of execution for the task name: task 3 = 12 : 14 : 06 Time of execution for the task name: task 2 = 12 : 14 : 06 Time of execution for the task name: task 1 = 12 : 14 : 07 Time of execution for the task name: task 3 = 12 : 14 : 07 Time of execution for the task name: task 2 = 12 : 14 : 07 Time of execution for the task name: task 1 = 12 : 14 : 08 Time of execution for the task name: task 3 = 12 : 14 : 08 Time of execution for the task name: task 2 = 12 : 14 : 08 task 1 is complete. task 3 is complete. Initialization time for the task name: task 4 = 12 : 14 : 09 Initialization time for the task name: task 5 = 12 : 14 : 09 task 2 is complete. Time of execution for the task name: task 4 = 12 : 14 : 10 Time of execution for the task name: task 5 = 12 : 14 : 10 Time of execution for the task name: task 4 = 12 : 14 : 11 Time of execution for the task name: task 5 = 12 : 14 : 11 Time of execution for the task name: task 4 = 12 : 14 : 12 Time of execution for the task name: task 5 = 12 : 14 : 12 Time of execution for the task name: task 4 = 12 : 14 : 13 Time of execution for the task name: task 5 = 12 : 14 : 13 Time of execution for the task name: task 4 = 12 : 14 : 14 Time of execution for the task name: task 5 = 12 : 14 : 14 task 4 is complete. task 5 is complete. Explanation: It is evident by looking at the output of the program that tasks 4 and 5 are executed only when the thread has an idle thread. Until then, the extra tasks are put in the queue. The takeaway from the above example is when you wants to execute 50 tasks but is not willing to create 50 threads. In such a case, one can create a pool of 10 threads. Thus, 10 out of 50 tasks are assigned, and the rest are put in the queue. Whenever any thread out of 10 threads becomes idle, it picks up the 11th task. The other pending tasks are treated the same way. Tuning the Thread PoolChoosing the right size for a thread pool depends on the number of available processors and the type of tasks being executed.
For I/O-bound tasks, the thread pool size can be estimated using this formula: Thread Pool Size = P × (1 + W / S) Where:
S = service time (CPU work) Example: Choosing Thread Pool SizeThe following example explains how thread pool size is selected based on task type. If a system has 4 processors and tasks are mostly CPU-bound, a thread pool size of 4 or 5 works best. This approach helps achieve better efficiency and balanced resource usage. Thread Pool MethodsJava thread pools provide several methods to manage task execution and control the lifecycle of threads. 1. submit(Runnable task)This method adds a task to the thread pool for execution. The task is placed in the queue and is executed by an available worker thread. Syntax: It has the following syntax: 2. shutdown()This method stops the thread pool gracefully. No new tasks are accepted, and all existing tasks are completed before the threads stop. Syntax: It has the following syntax: 3. shutdownNow()This method stops the thread pool immediately. It interrupts all running threads and clears the tasks waiting in the queue. Syntax: It has the following syntax: 4. getQueueSize()This method returns the number of tasks currently waiting in the task queue. Syntax: It has the following syntax: 5. getActiveCount()This method returns the number of threads that are actively executing tasks. Syntax: It has the following syntax: Risks and Considerations in Thread PoolsThe following are some common risks involved in using thread pools:
Next TopicThread Group in Java |
We request you to subscribe our newsletter for upcoming updates.