前言
在项目中遇到一个接口响应时间比较慢,查看代码发现是有几个SQL查询加在一起比较慢,在SQL方面做了优化后发现还是比较慢。
此时发现业务中只需要这几个sql的结果进行拼接处理,因此考虑使用线程池异步运行多个sql的方式来提高接口响应时间。
以下为相关代码实现
一、配置线程池
application.yml
thread-pool:
config:
core-size: 8
max-size: 16
queue-capacity: 64
keep-alive-seconds: 180
参数配置类
@Component
@ConfigurationProperties(prefix = "thread-pool.config")
@Data
public class TestThreadPoolConfig {
private Integer coreSize;
private Integer maxSize;
private Integer queueCapacity;
private Integer keepAliveSeconds;
}
线程池配置类
import org.springframework.beans.factory.annotation.Autowired;
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.RejectedExecutionHandler;
@Configuration
@EnableAsync
public class ThreadPoolConfig {
@Autowired
private TestThreadPoolConfig testThreadPoolConfig;
/**
* @return
*/
@Bean(name = "testExecutor")
public ThreadPoolTaskExecutor testThreadPoolExecutor() {
return getAsyncTaskExecutor("test-Executor-", testThreadPoolConfig.getCoreSize(),
testThreadPoolConfig.getMaxSize(), testThreadPoolConfig.getQueueCapacity(),
testThreadPoolConfig.getKeepAliveSeconds(), null);
}
/**
* 统一异步线程池
*
* @param threadNamePrefix
* @param corePoolSize
* @param maxPoolSize
* @param queueCapacity
* @param keepAliveSeconds
* @param rejectedExecutionHandler 拒接策略 没有填null
* @return
*/
private ThreadPoolTaskExecutor getAsyncTaskExecutor(String threadNamePrefix, int corePoolSize, int maxPoolSize, int queueCapacity, int keepAliveSeconds, RejectedExecutionHandler rejectedExecutionHandler) {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(corePoolSize);
taskExecutor.setMaxPoolSize(maxPoolSize);
taskExecutor.setQueueCapacity(queueCapacity);
taskExecutor.setThreadPriority(Thread.MAX_PRIORITY);//线程优先级
taskExecutor.setDaemon(false);//是否为守护线程
taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
taskExecutor.setThreadNamePrefix(threadNamePrefix);
taskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler);
taskExecutor.initialize();//线程池初始化
return taskExecutor;
}
}
二、服务类
@Autowired
private ThreadPoolTaskExecutor testExecutor;
@Override
public List test() {
CompletableFuture<List> future = CompletableFuture.supplyAsync(this::test01, testExecutor)
.exceptionally(this::handleException);
CompletableFuture<List> future2 = CompletableFuture.supplyAsync(this::test02, testExecutor)
.exceptionally(this::handleException);
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future, future2);
List vos = new ArrayList<>();
combinedFuture.thenAccept(v -> {
vos.addAll(future.join());
vos.addAll(future2.join());
System.out.println(vos);
});
combinedFuture.join();
return vos;
}
private List handleException(Throwable t) {
throw new RuntimeException("An exception occurred: " + t.getMessage(), t);
}
public List test01(){
System.out.println("执行test01");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
List list = new ArrayList();
list.add("111");
list.add("222");
System.out.println("执行test01结束");
return list;
}
public List test02(){
System.out.println("执行test02");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
List list = new ArrayList();
list.add("333");
list.add("444");
System.out.println("执行test02结束");
return list;
}