1、创建线程池配置文件 ThreadPoolConfig.java
@Configuration
@EnableAsync(proxyTargetClass = true)
public class ThreadPoolConfig {
@Bean
public TaskExecutor threadTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 线程池的线程最少数量
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
// 最大数量
executor.setMaxPoolSize(20);
// 队列数
executor.setQueueCapacity(1000);
executor.setThreadNamePrefix("custom-task-executor");
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
2.、注入 TaskExecutor
3、代码使用
原代码
// 获取订单详情
private List<OmsOrder> getOrderInfo(List<OmsOrder> records, String shopId) {
System.out.println("开始时间:" + System.currentTimeMillis());
for (OmsOrder od : records){
QueryWrapper<OmsOrderReturnApply> wrapper1 = new QueryWrapper<>();
QueryWrapper<OmsOrderSignature> wrapper2 = new QueryWrapper<>();
QueryWrapper<OmsReturnedMoney> wrapper3 = new QueryWrapper<>();
QueryWrapper<OmsOrderReceipt> wrapper4 = new QueryWrapper<>();
wrapper1.eq("order_id", od.getId());
wrapper2.eq("order_id", od.getId());
wrapper3.eq("order_id", od.getId());
wrapper4.eq("order_id", od.getId());
int type = od.getSelectType() != null && od.getSelectType() == 1 && StringUtils.isNotBlank(shopId) ? 1 : 0;
od.setOrderItemList(omsOrderItemMapper.getOrderItem(od.getId(), type, shopId));
List<OmsOrderReturnApply> applyList = omsOrderReturnApplyService.list(wrapper1);
List<OmsOrderReturnApply> applies = applyList.stream().peek(omsOrderReturnApply -> {
orderReturnProductService.getByApply(omsOrderReturnApply.getId());
}).collect(Collectors.toList());
od.setReturnList(applies);
od.setDeliveryList(omsDeliveryService.orderInfoList(od.getId()));
od.setRMoneyList(omsReturnedMoneyService.list(wrapper3));
od.setSignature(omsOrderSignatureService.getOne(wrapper2, false));
od.setReceiptList(orderReceiptService.list(wrapper4));
}
System.out.println("结束时间:" + System.currentTimeMillis());
return records;
}
运行时长:
第一次:开始时间 -> 1694077144004,结束时间 -> 1694077144042,时长:42
第二次:开始时间 -> 1694077196644,结束时间 -> 1694077196688,时长:44
第三次:开始时间 -> 1694077266602,结束时间 -> 1694077266651,时长:51
多线程代码
// 获取订单详情
private List<OmsOrder> getOrderInfo(List<OmsOrder> records, String shopId) {
System.out.println("开始时间:" + System.currentTimeMillis());
for (OmsOrder od : records){
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
int type = od.getSelectType() != null && od.getSelectType() == 1 && StringUtils.isNotBlank(shopId) ? 1 : 0;
od.setOrderItemList(omsOrderItemMapper.getOrderItem(od.getId(), type, shopId));
}, taskExecutor);
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
QueryWrapper<OmsOrderReturnApply> wrapper1 = new QueryWrapper<>();
List<OmsOrderReturnApply> applyList = omsOrderReturnApplyService.list(wrapper1);
List<OmsOrderReturnApply> applies = applyList.stream().peek(omsOrderReturnApply -> {
orderReturnProductService.getByApply(omsOrderReturnApply.getId());
}).collect(Collectors.toList());
od.setReturnList(applies);
}, taskExecutor);
CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
od.setDeliveryList(omsDeliveryService.orderInfoList(od.getId()));
}, taskExecutor);
CompletableFuture<Void> future4 = CompletableFuture.runAsync(() -> {
QueryWrapper<OmsReturnedMoney> wrapper3 = new QueryWrapper<>();
wrapper3.eq("order_id", od.getId());
od.setRMoneyList(omsReturnedMoneyService.list(wrapper3));
}, taskExecutor);
CompletableFuture<Void> future5 = CompletableFuture.runAsync(() -> {
QueryWrapper<OmsOrderSignature> wrapper2 = new QueryWrapper<>();
wrapper2.eq("order_id", od.getId());
od.setSignature(omsOrderSignatureService.getOne(wrapper2, false));
}, taskExecutor);
CompletableFuture<Void> future6 = CompletableFuture.runAsync(() -> {
QueryWrapper<OmsOrderReceipt> wrapper4 = new QueryWrapper<>();
wrapper4.eq("order_id", od.getId());
od.setReceiptList(orderReceiptService.list(wrapper4));
}, taskExecutor);
//将上面的线程池任务装进数组
CompletableFuture[]completableFutures = Stream.of(future1,future2,future3,future4,future5,future6).collect(Collectors.toList()).toArray(new CompletableFuture[6]);
//当数组里的所有交给线程池的任务都执行完后,才会继续向下执行;相当于阻塞
CompletableFuture.allOf(completableFutures).join();
}
System.out.println("结束时间:" + System.currentTimeMillis());
return records;
}
运行结果:
第一次:开始时间 -> 1694077465585,结束时间 -> 1694077465597, 时长:12
第二次:开始时间 -> 1694077544172,结束时间 -> 1694077544207, 时长:35
第三次:开始时间 -> 1694077606195,结束时间 -> 1694077606229, 时长:24
结论:使用多线程异步执行能够优化执行时长