SpringBoot 使用线程池
前言
一、SpringBoot 中线程池的使用
在实际项目中我们经常会遇到这样的场景需求,例如需要一个接口需要执行一个需要花费时间很长执行的任务,但是我们不想由于这个任务导致接口主线程阻塞,这时候我们需要其它线程去执行这个任务,这就需要使用到线程池。
1.1、配置线程池
@Configuration
// 开启多线程
@EnableAsync
public class ThreadPoolConfig {
@Value("${myThreadPool.maxPoolSize}")
private Integer maxPoolSize;
@Value("${myThreadPool.queueCapacity}")
private Integer queueCapacity;
@Value("${myThreadPool.keepAliveSeconds}")
private Integer keepAliveSeconds;
@Value("${myThreadPool.threadNamePrefix}")
private String threadNamePrefix;
@Value("${myThreadPool.waitForTasksToCompleteOnShutdown}")
private Boolean waitForTasksToCompleteOnShutdown;
@Bean("taskExecutor")
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数等于系统核数
int availableProcessors = Runtime.getRuntime().availableProcessors();
// 设置核心线程数
executor.setCorePoolSize(availableProcessors);
// executor.setCorePoolSize(corePoolSize);
// 设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 设置队列大小
executor.setQueueCapacity(queueCapacity);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程满了之后由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 设置默认线程名称
executor.setThreadNamePrefix(threadNamePrefix);
// 等待所有任务执行完成后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown);
// 执行初始化
executor.initialize();
return executor;
}
}
线程池的参数配置在application-dev.yml中,具体如下
myThreadPool:
maxPoolSize: 20
queueCapacity: 2048
keepAliveSeconds: 60
threadNamePrefix: HuDu
waitForTasksToCompleteOnShutdown: true
1.2、创建异步调用接口以及实现类
这里主要是使用到@Async
这个注解来声明使用XXX线程池异步执行该方法,代码如下
public interface ThreadService {
void syncFile();
}
@Component
@Slf4j
public class ThreadServiceImpl implements ThreadService {
// 此操作不会影响原有的主线程
@Async
@Override
public void syncFile() {
log.info("syncFile {}",Thread.currentThread().getName());
}
}
1.3、线程池测试
@Test
public void threadPoolTest() {
for (int i = 0; i < 20; i++) {
threadPoolService.syncFile();
}
log.info("主线程 {} 结束执行",Thread.currentThread().getName());
}
执行结果如下
本作品采用《CC 协议》,转载必须注明作者和本文链接