Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

For resource pool technology, I believe we have long been exposed to, such as database connection pool, common c3P0, DBCP and so on, and threads also have a corresponding pool, called thread pool.

Java provides the Executors class to create a thread pool, such as:

public static void main(String[] args) {
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    Thread thread = new Thread(() -> {
        System.out.println("hello world!");
    });
    executorService.execute(thread);
}
Copy the code

The newFixedThreadPool() method obtains a thread pool with a specified number of threads.

Such as:

public static void main(String[] args) {
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Thread thread = new Thread(() -> {
        System.out.println("hello world!");
    });
    executorService.execute(thread);
}
Copy the code

The newSingleThreadExecutor() method gives you a thread pool of 1 threads.

There are:

public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    Thread thread = new Thread(() -> {
        System.out.println("hello world!");
    });
    executorService.execute(thread);
}
Copy the code

The newCachedThreadPool() method gives you a thread pool that creates as many threads as you need, based on the number of tasks.

We found that various thread pools can be created by using the Executors class, but the Alibaba Java Development Manual doesn’t recommend using the Executors class to create threads. Instead, you should manually create threads by yourself:

So how do you create a thread pool manually?

public static void main(String[] args) {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5.10.5L,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(3),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());
    executor.execute(() -> {
        System.out.println("hello world");
    });
}
Copy the code

The ThreadPoolExecutor object returns a thread pool with seven parameters, as follows:

  1. CorePoolSize: number of core threads
  2. MaximumPoolSize: indicates the maximum number of threads
  3. KeepAliveTime: indicates the idle time
  4. Unit: unit of idle time
  5. WorkQueue: indicates a task queue
  6. ThreadFactory: Factory for creating threads
  7. Handler: saturation policy

Said the core number of threads in the thread pool threads at the core, they are in any case will not be recycled, but wait for the arrival of the task, the maximum number of threads is a thread pool to create the maximum number of threads, leisure time said a non-core threads waiting for leisure time after there is still no task execution, the thread will be recycled, The factory for creating threads is used to specify how threads are created, usually by default, and the saturation policy indicates how the excess tasks should be handled once the thread pool reaches its maximum number of threads.

A simple example, there are 10 waiting for task execution, because our core number of threads to 5, so the thread pool will create five threads used to perform one of the five tasks, the remaining five task will be put into the task queue, and task queue has a capacity of only 3, so the task queue can only put down three tasks, the remaining two tasks cannot be put into the queue, The thread pool creates two non-core threads to execute them, and if the maximum number of threads in the pool is reached, a saturation policy, such as the CallerRunsPolicy policy here, is triggered, which simply discards the new task.