本章节为基于SpringBoot 通过注解方式实现ThreadPoolExecutor实例,步骤过程如下:
1、定义ExecutorConfig类,用于配置、初始化ThreadPoolTaskExecutor类
package com.example.threadpooldemo.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Bean(name = "asyncServiceExecutor")
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
2、定义ThreadPoolTaskExecutor类属性配置源文件-application.properties
# 异步线程配置
# 配置核心线程数
async.executor.thread.core_pool_size = 5
# 配置最大线程数
async.executor.thread.max_pool_size = 5
# 配置队列大小
async.executor.thread.queue_capacity = 99999
# 配置线程池中的线程的名称前缀
async.executor.thread.name.prefix = async-service-
3、定义异步服务接口和实现类
package com.example.threadpooldemo.config;
public interface AsyncService {
/**
* 执行异步任务
* 可以根据需求,自己加参数拟定,我这里就做个测试演示
*/
void executeAsync();
}
package com.example.threadpooldemo.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncServiceImpl implements AsyncService {
private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);
@Override
@Async("asyncServiceExecutor")
public void executeAsync() {
logger.info("start executeAsync");
System.out.println("异步线程要做的事情");
System.out.println("可以在这里执行批量插入等耗时的事情");
logger.info("end executeAsync");
}
}
实现类AsyncServiceImpl 中public void executeAsync() 通过@Async("asyncServiceExecutor")注解 关联ExecutorConfig类 @Bean(name = "asyncServiceExecutor") ,即executeAsync方法进入的线程池是asyncServiceExecutor方法来创建
4、Controller:通过注解@Autowired注入并调用Service
package com.example.threadpooldemo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/*Spring Restful风格*/
@RestController
public class AyncControlller {
@Autowired
private AsyncService asyncService;
/*外部资源映射-http://localhost:8080/async*/
@GetMapping("/async")
public void async(){
asyncService.executeAsync();
}
}
5、测试-postmain [http://localhost:8080/async]
2021-05-17 17:13:59.331 INFO 17516 --- [async-service-1] c.e.t.config.AsyncServiceImpl : start executeAsync
异步线程要做的事情
可以在这里执行批量插入等耗时的事情
2021-05-17 17:13:59.332 INFO 17516 --- [async-service-1] c.e.t.config.AsyncServiceImpl : end executeAsync
2021-05-17 17:14:00.047 INFO 17516 --- [async-service-2] c.e.t.config.AsyncServiceImpl : start executeAsync
异步线程要做的事情
可以在这里执行批量插入等耗时的事情
2021-05-17 17:14:00.047 INFO 17516 --- [async-service-2] c.e.t.config.AsyncServiceImpl : end executeAsync
2021-05-17 17:14:00.754 INFO 17516 --- [async-service-3] c.e.t.config.AsyncServiceImpl : start executeAsync
异步线程要做的事情
可以在这里执行批量插入等耗时的事情
2021-05-17 17:14:00.754 INFO 17516 --- [async-service-3] c.e.t.config.AsyncServiceImpl : end executeAsync
2021-05-17 17:14:01.429 INFO 17516 --- [async-service-4] c.e.t.config.AsyncServiceImpl : start executeAsync
异步线程要做的事情
可以在这里执行批量插入等耗时的事情
2021-05-17 17:14:01.429 INFO 17516 --- [async-service-4] c.e.t.config.AsyncServiceImpl : end executeAsync
2021-05-17 17:14:02.052 INFO 17516 --- [async-service-5] c.e.t.config.AsyncServiceImpl : start executeAsync
异步线程要做的事情
可以在这里执行批量插入等耗时的事情
2021-05-17 17:14:02.052 INFO 17516 --- [async-service-5] c.e.t.config.AsyncServiceImpl : end executeAsync
2021-05-17 17:14:02.687 INFO 17516 --- [async-service-1] c.e.t.config.AsyncServiceImpl : start executeAsync
异步线程要做的事情
可以在这里执行批量插入等耗时的事情
2021-05-17 17:14:02.687 INFO 17516 --- [async-service-1] c.e.t.config.AsyncServiceImpl : end executeAsync
默认线程数为5.
PS:pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>threadpooldemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>threadpooldemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>