1、线程池类
@Configuration
@Getter
public class GisOrderThreadPool {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); // 核心线程数
executor.setMaxPoolSize(20); // 最大线程数
executor.setQueueCapacity(500); // 队列容量
executor.setThreadNamePrefix("GisOrderExecutor-"); // 线程名的前缀
executor.initialize();
return executor;
}
}
2、异步查询函数: 分页查询再汇总
//异步 分页查询再汇总
public List<GisOrderDto> processGisInstallOrderDtoListAsyn(GisOrderParam gisOrderParam) {
List<GisOrderDto> list = new ArrayList<>();
int pageSize = 1500; // 每页查询的数量,根据实际需求调整
//数据总量
int totalCount = gisOrderDAO.selectGisInstallOrderCount(gisOrderParam);
//分批的总次数
int totalPage = (int) Math.ceil((double) totalCount / pageSize);
//用spring托管的线程池,避免经常创建和释放线程池
Executor executor = threadPool.taskExecutor().getThreadPoolExecutor();
List<CompletableFuture<List<GisOrderDto>>> futures = new ArrayList<>();
for (int currentPage = 1; currentPage <= totalPage; currentPage++) {
//用于lambda 表达式内部必须是final,所以currentPage不能直接用, 为每个线程创建新的finalCurrentPage
int finalCurrentPage = currentPage;
//由于gisOrderParam是共享的,set内容 有多线程安全问题,所以为每个线程新new一个 localParam
GisOrderParam localParam = new GisOrderParam();
BeanUtils.copyProperties(gisOrderParam, localParam);
//每个分页查询都会被包装成一个CompletableFuture,并提交给线程池进行异步处理
CompletableFuture<List<GisOrderDto>> future = CompletableFuture.supplyAsync(() -> {
localParam.setOffset((finalCurrentPage - 1) * pageSize);
localParam.setLimit(pageSize);
return gisOrderDAO.selectGisInstallOrder(localParam);
}, executor);
futures.add(future);
}
//使用CompletableFuture.allOf()等待所有任务完成,然后将结果合并到最终的list中
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenAccept(v -> {
for (CompletableFuture<List<GisOrderDto>> future : futures) {
try {
list.addAll(future.get());
}
catch (Exception e) {
logger.info("分批查询异常");
}
}
})
.join();
return list;
}
3、若不需要接收返回的信息,用 runAsync()
多线程异步 发送信息提醒并入库
//多线程异步 发送信息提醒并入库
for (OrderWarnTaskPO po : installSxList) {
CompletableFuture.runAsync(() -> {
sendMsgAndInsert(po, "装机", "首响");
}, executor);
}