[Thread pool] ThreadPoolTaskExecutor thread pool used in the project

When concurrent or asynchronous operations, ThreadPoolTaskExecutor will be used. The thread pool used in the project is ThreadPoolTaskExecutor. This class is under the spring package and is a thread pool class provided by spring. Here we will focus on the configuration and details of the Spring thread pool ThreadPoolTaskExecutor.

  1. The ThreadPoolTaskExecutor configuration can be created based on the xml configuration, which can be configured in spring.xml
 <!-- spring thread pool executor -->           
 2     <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
 3         <!-- 线程池维护线程的最少数量 -->
 4         <property name="corePoolSize" value="5" />
 5         <!-- 允许的空闲时间 -->
 6         <property name="keepAliveSeconds" value="200" />
 7         <!-- 线程池维护线程的最大数量 -->
 8         <property name="maxPoolSize" value="10" />
 9         <!-- 缓存队列 -->
10         <property name="queueCapacity" value="20" />
11         <!-- 对拒绝task的处理策略 -->
12         <property name="rejectedExecutionHandler">
13             <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
14         </property>
15     </bean>

Attribute field description

corePoolSize: the minimum number of threads for thread pool maintenance

keepAliveSeconds: Allowed free time

maxPoolSize: the maximum number of threads for thread pool maintenance

queueCapacity: cache queue

rejectedExecutionHandler: the processing strategy for rejected tasks

The rejectedExecutionHandler field is used to configure rejection strategies. Common rejection strategies are as follows:

AbortPolicy: The handler for rejected tasks, it will throw RejectedExecutionException

CallerRunsPolicy: A handler for rejected tasks, which runs the rejected tasks directly in the calling thread of the execute method.

DiscardOldestPolicy: A handler for rejected tasks, which abandons the oldest unprocessed request, and then retry execute.

DiscardPolicy: A handler for rejected tasks. By default, it will discard rejected tasks.

In the project, inject the thread pool by automatic injection

@Resource(name="taskExecutor")
ThreadPoolTaskExecutor taskExecutor;
// 也可以直接用@Autowried
@AutoWired
ThreadPoolTaskExecutor taskExecutor

Also configure the thread pool by configuring the class, and then inject

@Configuration
public class ExecturConfig {
    
    
    @Bean("taskExector")
    public Executor taskExector() {
    
    
 
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int i = Runtime.getRuntime().availableProcessors();//获取到服务器的cpu内核
        executor.setCorePoolSize(5);//核心池大小
        executor.setMaxPoolSize(100);//最大线程数
        executor.setQueueCapacity(1000);//队列程度
        executor.setKeepAliveSeconds(1000);//线程空闲时间
        executor.setThreadNamePrefix("tsak-asyn");//线程前缀名称
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//配置拒绝策略
        return executor;
    }

Submit tasks:
void execute(Runnable command)
Use execute(Runnable)
for tasks with no return value, use submit(Runnable) for tasks with return value

Processing flow
1. When a task is submitted to the thread pool, first check whether the core threads of the thread pool are all executing tasks, if not, select a thread to execute the task, and if yes, execute the second step.
2. Check whether the core thread pool is full, create a thread to perform the task if dissatisfied, otherwise perform the third step.
3. Check whether the task queue is full, and store the task in the task queue when dissatisfied, otherwise perform the fourth step.
4. Check whether the thread pool is full, create a thread to perform tasks when dissatisfied, otherwise, process tasks that cannot be performed according to the strategy.
Close the thread pool
showdow () implementation code:

if (this.executor != null) {
    
    
if (this.waitForTasksToCompleteOnShutdown) {
    
    
this.executor.shutdown();//中断未执行完的线程
} else {
    
    
Iterator var1 = this.executor.shutdownNow().iterator();
while(var1.hasNext()) {
    
    
Runnable remainingTask = (Runnable)var1.next();
this.cancelRemainingTask(remainingTask);//取消所有剩下需要执行的线程
}
}

Call shutdown or shutdownNow, neither will accept new tasks, and interrupt the thread by calling the interrupt method of the thread to be stopped, it is possible that the thread will never be interrupted, the difference is that shutdownNow will first set the state of the thread pool STOP, and then try to stop all threads (may result in some tasks not completed) and then return to the list of unexecuted tasks. And shutdown just sets the state of the thread pool to shutdown, then interrupts all threads that are not performing tasks, and executes the remaining tasks.

Configure the number of threads
If it is a CPU-intensive task, the number of threads in the thread pool should be as small as possible, generally the number of CPUs + 1 thread.
If it is an IO-intensive task, then the threads of the thread pool can be large, such as the number of 2*CPU.
For mixed tasks, if they can be split, they can be split into CPU-intensive and IO-intensive to improve execution efficiency; if they cannot be split, the number of threads in the thread pool can be adjusted according to the actual situation.


Common status for monitoring thread pool status :
taskCount: The number of tasks that the thread needs to execute.
completedTaskCount: The number of tasks completed by the thread pool during its operation.
largestPoolSize: The largest number of threads ever created by the thread pool.
getPoolSize gets the number of threads in the current thread pool.
getActiveCount: Get the number of active threads

if(executor.getActiveCount() > (executor.getPoolSize()-1)){
    
    
	//核心线程池已满
	return;
}
Runnable runnable = ()->{
    
    
	//业务方法
};
executor.executor(runnable);

Guess you like

Origin blog.csdn.net/weixin_42777004/article/details/107880975