需求
前两天做项目的时候,想提高一下插入表的性能优化,因为是两张表,先插旧的表,紧接着插新的表,一万多条数据就有点慢了
思路
后面就想到了线程池ThreadPoolExecutor,而用的是Spring Boot项目,可以用Spring提供的对ThreadPoolExecutor封装的线程池ThreadPoolTaskExecutor,直接使用注解启用
实现
- 线程池配置类
先创建一个线程池的配置,让Spring Boot加载,用来定义如何创建一个ThreadPoolTaskExecutor,要使用@Configuration和@EnableAsync这两个注解,表示这是个配置类,并且是线程池的配置类
package com.threadpooltaskexecutor.threadpooltaskexecutordemo.config;
import lombok.extern.slf4j.Slf4j;
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;
/**
* @version 1.0
* @Description 线程池配置类 异步
* @Date 2021/8/13 11:04
* @Author wangyun
*/
@Configuration
@EnableAsync
@Slf4j
public class ExecutorConfig {
/**
* 核心线程数 数量
*/
@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("asyncServiceExecutor")
public Executor asyncServiceExecutor(){
log.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
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;
}
}
- 创建一个Service接口,是异步线程的接口 ```java package com.threadpooltaskexecutor.threadpooltaskexecutordemo.service;
/**
- @version 1.0
- @Description
- @Date 2021/8/13 11:38
- @Author wangyun */
public interface AsyncService {
/**
* 执行异步任务
* 可以根据需求,自己加参数拟定,我这里就做个测试演示
*
*/
void executeAsync() throws InterruptedException;
}
3. service 实现
```java
package com.threadpooltaskexecutor.threadpooltaskexecutordemo.service.impl;
import com.threadpooltaskexecutor.threadpooltaskexecutordemo.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* @version 1.0
* @Description
* @Date 2021/8/13 11:39
* @Author wangyun
*/
@Service
@Slf4j
public class AsyncServiceImpl implements AsyncService {
/**
* 执行异步任务
* 可以根据需求,自己加参数拟定,我这里就做个测试演示
*/
@Override
@Async("asyncServiceExecutor") //这里是异步线程池的名字
public void executeAsync() throws InterruptedException {
log.info("In AsyncServiceImpl Class, begin execute executeAsync");
log.info("异步线程要做的事情");
TimeUnit.SECONDS.sleep(5); //模拟要执行耗时的操作
log.info("可以在这里执行批量插入等耗时的事情");
log.info("In AsyncServiceImpl Class, end execute executeAsync");
}
}
- yml
async:
executor:
thread:
core_pool_size: 5
max_pool_size: 5
queue_capacity: 99999
name:
prefix: async-service-
代码
注意:下载后,请将.pdf后缀去除
threadpooltaskexecutor-demo.rar.pdf