1. yaml文件配置
# 线程池配置
thread:
pool:
# 核心线程数
corePoolSize: 8
# 最大线程数
maxPoolSize: 16
# 线程队列长度
queueCapacity: 300
# 超过核心线程数的线程所允许的空闲时间
keepAliveSeconds: 300
2. 线程池配置类
ThreadPoolTaskExecutor有多个实例对象时,加注解@Primary,告诉spring优先使用哪个实例
package cn.monkey.code.demo;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线程池配置
* ThreadPoolTaskExecutor的使用
* 自定义多个线程池 & 指定线程池使用
*/
@Data
@Component
@ConfigurationProperties(prefix = "thread.pool")
public class ThreadPoolTaskExecutorConfig {
private Integer corePoolSize;
private Integer maxPoolSize;
private Integer queueCapacity;
private Integer keepAliveSeconds;
// 自定义ThreadPoolTaskExecutor线程池
@Bean(name = "customThreadPoolTaskExecutor")
public ThreadPoolTaskExecutor customThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置线程池参数
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setThreadNamePrefix("myExecutor--");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
// 修改拒绝策略为使用当前线程执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化线程池
executor.initialize();
return executor;
}
// 自定义ThreadPoolTaskExecutor线程池
@Primary
@Bean(name = "customThreadPoolTaskExecutor11111")
public ThreadPoolTaskExecutor customThreadPoolTaskExecutor1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置线程池参数
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setThreadNamePrefix("myExecutor11111--");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
// 修改拒绝策略为使用当前线程执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化线程池
executor.initialize();
return executor;
}
}
3. 测试自定义线程池
有@Qualifier该注解的会找指定名称的线程池,如果没有@Qualifier则找有@Primary注解的默认线程池
package cn.monkey.code.demo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.junit4.SpringRunner;
/**
* SpringBoot中自定义多个线程池
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SettingsApplication.class)
@Slf4j
public class SpringBootCustomThreadPoolTest {
// 会去匹配 @Bean("customThreadPoolTaskExecutor") 这个线程池
@Qualifier("customThreadPoolTaskExecutor")
@Autowired
private ThreadPoolTaskExecutor customThreadPool1;
// 会去匹配有@Primary注解的 @Bean("customThreadPoolTaskExecutorPrimary") 这个线程池
@Autowired
private ThreadPoolTaskExecutor customThreadPool2;
@Test
public void testCustomThreadPoolTaskExecutor() {
doFirst();
asyncTask();
asyncTask2();
doFinish();
}
private void doFirst() {
log.info("执行异步任务之前");
}
private void asyncTask() {
for (int j = 0; j < 5; j++) {
final int index = j;
customThreadPool1.execute(new Runnable() {
@Override
public void run() {
log.info("###SpringBoot中使用自定义线程池{} 创建线程 异步执行:{}", customThreadPool1.getThreadNamePrefix() ,index);
}
});
}
}
private void asyncTask2() {
customThreadPool2.getThreadPoolExecutor().toString();
for (int j = 0; j < 5; j++) {
final int index = j;
customThreadPool2.execute(new Runnable() {
@Override
public void run() {
log.info("###SpringBoot中使用自定义线程池{} 创建线程 异步执行:{}", customThreadPool2.getThreadNamePrefix(), index);
}
});
}
}
private void doFinish() {
log.info("执行异步任务结束");
}
}
4. 测试结果
11:06:23.047 nacos [main] INFO c.m.c.d.SpringBootCustomThreadPoolTest - 执行异步任务之前
11:06:23.049 nacos [myExecutor--4] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutor-- 创建线程 异步执行:3
11:06:23.049 nacos [myExecutor--3] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutor-- 创建线程 异步执行:2
11:06:23.049 nacos [myExecutor--1] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutor-- 创建线程 异步执行:0
11:06:23.049 nacos [myExecutor--2] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutor-- 创建线程 异步执行:1
11:06:23.049 nacos [myExecutor--5] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutor-- 创建线程 异步执行:4
11:06:23.051 nacos [myExecutorPrimary--1] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutorPrimary-- 创建线程 异步执行:0
11:06:23.051 nacos [myExecutorPrimary--2] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutorPrimary-- 创建线程 异步执行:1
11:06:23.051 nacos [myExecutorPrimary--3] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutorPrimary-- 创建线程 异步执行:2
11:06:23.051 nacos [main] INFO c.c.h.m.SpringBootCustomThreadPoolTest - 执行异步任务结束
11:06:23.051 nacos [myExecutorPrimary--4] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutorPrimary-- 创建线程 异步执行:3
11:06:23.051 nacos [myExecutorPrimary--5] INFO c.m.c.d.SpringBootCustomThreadPoolTest - ###SpringBoot中使用自定义线程池myExecutorPrimary-- 创建线程 异步执行:4