preface
In the peacetime development, often encountered such things, such as database connection pool, Web request is also the use of pooling technology, but we are less direct contact;
The body of the
What is a thread pool
A simple point of understanding is a pool of threads, a pooling idea for a certain number of threads management, such as: thread creation, destruction, task execution, etc.;
Thread pool flow
- Submit tasks to the thread pool
- Check whether the number of core threads in the thread pool is full. If not, create a core thread to handle the task. Otherwise, proceed to the next process
- Check whether the number of queues in the thread pool is full. If not, add the task to the waiting queue; otherwise, proceed to the next flow
- Check whether the maximum number of threads in the thread pool is full. If not, create non-core threads to process tasks. Otherwise, proceed to the next process
- The task is processed according to the reject policy configured by the thread pool
The flow chart is as follows:
The thread pool
ThreadPoolExecutor
Create a thread pool from ThreadPoolExecutor in Java with the following parameters:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {}
Copy the code
Parameter Description:
-
corePoolSize
- The number of threads that remain in the thread pool, even if they are idle, unless set
allowCoreThreadTimeOut
- Threads in the thread pool will not be created until the task is submitted, if the thread pool’s
prestartAllCoreThreads()
The thread pool creates the core threads ahead of time and starts them up
- The number of threads that remain in the thread pool, even if they are idle, unless set
-
maximumPoolSize
- The maximum number of threads allowed to be created by the thread pool. When the queue configured by the thread pool is full, non-core threads will continue to be created until the maximum number of threads is created
-
keepAliveTime
- The lifetime of idle (non-core) threads when the number of threads is greater than the number of core threads, after which idle threads are reclaimed
-
unit
keepAliveTime
Unit of time
-
workQueue
- A work queue that saves tasks before they are executed. This queue stores only the number of tasks
execute
Method submittedRunnable
task
- A work queue that saves tasks before they are executed. This queue stores only the number of tasks
-
threadFactory
- Thread creation factory, which is used when a new thread is created
- This is where you typically set the name of the thread (implementation
ThreadFactory
Of the interfacenewThread
Methods)
-
handler
- There are four main types of saturation strategies
- This policy is used when the number of work queues and threads reaches the maximum
Four rejection strategies:
- AbortPolicy: Throws an exception. Default option
- DiscardPolicy: Discards tasks directly
- DiscardOldestPolicy: Discards the oldest task in the queue and saves the new one
- CallerRunsPolicy: Returned to the calling thread to handle the task
Custom rejection policy: Define a class that implements the rejectedExecution method of the RejectedExecutionHandler interface
Four types of blocking queues:
- ArrayBlockingQueue: Array-based bounded blocking queue, initialized to a specified capacity, first-in, first-out
- LinkedBlockingQueue: An unbounded block queue based on a linked list structure, with which the pool of threads has not reached its maximum number
- SynchronousQueue: synchronousblocking queue; Each insertion queue must wait for another thread to remove it, and vice versa;
- PriorityBlockingQueue: Priority queue
- DelayedWorkQueue: indicates the delay queue
ScheduledThreadPoolExecutor
Static class
Running status of ThreadPoolExecutor
ThreadPoolExecutor can run in the following states:
- RUNNING: Receives new tasks and processes tasks in the queue
- SHUTDOWN: does not accept new tasks, but processes tasks in the queue
- STOP: does not accept new tasks, does not process tasks in the queue, and interrupts tasks in progress
- TIDYING: All tasks end, thread count is zero, thread pool status changes
TIDYING
Will runterminated
methods - TERMINATED:
terminated
Method completed
The flow chart is as follows:
Several ways to create threads
The following ways to create thread pools all use ThreadPoolExecutor to create thread pools;
- Executors.newCachedThreadPool();
The source code is as follows:
public static ExecutorService newCachedThreadPool(a) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
Copy the code
-
The core thread is 0
-
The maximum number of threads is integer.max_value
-
The idle thread lifetime is 60 seconds
-
Use SynchronousQueue
- Executors.newFixedThreadPool(15);
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
Copy the code
- Core threads are equal to the maximum number of threads
- The idle thread lifetime is 0
- Use unbounded blocking queues
- Executors.newScheduledThreadPool(1);
Scheduled task thread pool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
Copy the code
- The number of core threads is corePoolSize and the maximum number of threads is integer.max_value
- The idle thread lifetime is 0
- Use the internal delay queue DelayedWorkQueue
- Executors.newSingleThreadExecutor();
There is only one core thread, and the largest thread is the core thread
public static ExecutorService newSingleThreadExecutor(a) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1.1.0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Copy the code
- The number of core threads is the same as the maximum number of threads
- The idle thread lifetime is 0
- Use the unbounded blocking queue LinkedBlockingQueue
Thread pool monitoring
Thread pool built-in methods:
The methods in the figure above give you a look inside the thread pool at runtime; In addition, ThreadPoolExecutor has three methods that can be customized:
-
Void beforeExecute(Thread t, Runnable r) This method is executed before a task is executed
-
Void afterExecute(Runnable r, Throwable t) afterExecute(Runnable r, Throwable t) afterExecute(Runnable r, Throwable t) afterExecute(Runnable r, Throwable t)
-
The void terminated() thread pool is terminated by calling the shutdown(),shutdownNow(),remove methods, and so on.
The last
This article has only covered some basic information about thread pools;
reference
- Thread pools in Java
- Java thread pool analysis
- Java thread pool details
- Understanding Java thread pools in depth: ThreadPoolExecutor
- Java High Concurrency series – Day 18: Java Thread Pools, this article is enough
- Implementation principle of Java thread pool and its practice in Meituan business
- Java thread pool parsing