How to create a thread pool using ThreadPoolExecutor class

Introduction

A thread pool is a collection of threads that can be used to execute tasks concurrently. The ThreadPoolExecutor class provides many methods that can be used to configure and manage the thread pool. This class also provides a lot of customization options. We can specify the number of threads, the task queue size, the thread factory, and the rejection handler.

Methods

The ThreadPoolExecutor class provides the following methods:

  • submit(Task task): It submits a task to the thread pool for execution.
  • shutdown(): It shuts down the thread pool.
  • isShutdown(): It returns a boolean indicating whether the thread pool has been shut down.
  • getThreads(): It returns an iterator over the threads in the pool.
  • awaitTermination(long timeout, TimeUnit unit): It blocks until all tasks have been completed or the specified timeout has elapsed.

The ThreadPoolExecutor constructor

The ThreadPoolExecutor class provides a number of constructors that can be used to create a thread pool. The syntax of the most commonly used constructor is shown below:

ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue);
Syntax of constructor for ThreadPoolExecutor class

Below are the details of the parameters:

  • The corePoolSize parameter specifies the minimum number of threads that should be in the thread pool.
  • The maximumPoolSize parameter specifies the maximum number of threads that can be in the thread pool.
  • The keepAliveTime parameter specifies how long a thread should remain idle before it is removed from the pool.
  • The unit parameter specifies the time unit for the keepAliveTime parameter.
  • The workQueue parameter specifies the queue that will be used to store tasks that are waiting to be executed.

Code example

The example of thread pool using ThreadPoolExecutor class is as follows:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
class ThreadPoolExample {
public static void main(String[] args) {
// create a fixed size thread pool with 5 threads
ThreadPoolExecutor executor =
new ThreadPoolExecutor(2, 5, 200,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(5));
// submit tasks to be executed by the pool
for (int i = 0; i < 10; i++) {
executor.execute(new Task(i));
}
// shutdown the pool
executor.shutdown();
}
}
class Task implements Runnable {
private int taskId;
public Task(int id) {
this.taskId = id;
}
public void run() {
System.out.println("Starting task " + taskId);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finishing task " + taskId);
}
}

Code explanation

  • Lines 9 to 12: We create a thread pool that uses an ArrayBlockingQueue to store the tasks. The ArrayBlockingQueue has a size of 5, which means that it can store at most 5 tasks. The thread pool is 2 core threads and a maximum of 5 threads. We have also specified that the idle threads should be terminated after 200 milliseconds.

We submit 10 tasks to be executed by the pool. Since the pool size is only 2, only 2 tasks are executed concurrently and the others are queued.

Note: Even though we have submitted 10 tasks, only 2 threads are created and the tasks are executed one after the other.

Free Resources