将需要串行执行的任务,改成并行执行,减少接口调用的响应时间,提高接口性能
简单举例:
查询标签列表需要调用不同系统的不同服务接口来获取,串行调用会很耗费时间
改成下图调用方式:
串行调用改成并行调用,减少了服务间相互调用的等待时间,提升了接口性能
代码示例:
/**
* 自定义线程池配置
*/
@Configuration
public class ThreadPoolConfig {
// 核心线程数 20
@Value("${lease.thread.core-size}")
private Integer coreSize;
// 最大线程数 100
@Value("${lease.thread.max-size}")
private Integer maxSize;
// 空闲线程存活时间 10
@Value("${lease.thread.keep-alive-time}")
private Integer keepAliveTime;
@Bean
public ThreadPoolExecutor threadPoolExecutor() {
return new ThreadPoolExecutor(coreSize,
maxSize,
keepAliveTime,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
}
使用CompletableFuture和线程池,改写查询方法
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
implements RoomInfoService {
@Autowired
private RoomInfoMapper roomInfoMapper;
......
@Autowired
private RoomLeaseTermService roomLeaseTermService;
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
@Override
public RoomDetailVo getDetailById(Long id) {
RoomDetailVo resultVo = new RoomDetailVo();
// 获取房间详情和公寓信息
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
RoomInfo roomInfo = this.getById(id);
BeanUtils.copyProperties(roomInfo, resultVo);
return roomInfo;
}, threadPoolExecutor).thenAcceptAsync((roomInfo) -> {
resultVo.setApartmentInfo(apartmentInfoService.getById(roomInfo.getApartmentId()));
}, threadPoolExecutor);
// 获取图片列表
CompletableFuture<Void> graphVosFuture = CompletableFuture.runAsync(() -> {
List<GraphInfo> graphInfos = graphInfoService.lambdaQuery()
.eq(GraphInfo::getItemId, id)
.eq(GraphInfo::getItemType, ItemType.ROOM)
.list();
List<GraphVo> graphVos = graphInfos.stream().map(item -> {
GraphVo graphVo = new GraphVo();
BeanUtils.copyProperties(item, graphVo);
return graphVo;
}).collect(Collectors.toList());
resultVo.setGraphVoList(graphVos);
}, threadPoolExecutor);
// 获取属性信息列表
CompletableFuture<Void> attrValueVosFuture = CompletableFuture.runAsync(() -> {
resultVo.setAttrValueVoList(attrValueMapper.getAttrValueVosByRoomId(id));
}, threadPoolExecutor);
// 获取配套信息列表
CompletableFuture<Void> facilityInfoFuture = CompletableFuture.runAsync(() -> {
resultVo.setFacilityInfoList(facilityInfoMapper.getFacilityInfos(id));
}, threadPoolExecutor);
// 获取标签信息列表
CompletableFuture<Void> labelInfoFuture = CompletableFuture.runAsync(() -> {
resultVo.setLabelInfoList(labelInfoMapper.getLabelInfos(id));
}, threadPoolExecutor);
// 获取支付方式列表
CompletableFuture<Void> paymentTypeFuture = CompletableFuture.runAsync(() -> {
resultVo.setPaymentTypeList(paymentTypeMapper.getPaymentTypes(id));
}, threadPoolExecutor);
// 获取可选租期列表
CompletableFuture<Void> leaseTermFuture = CompletableFuture.runAsync(() -> {
resultVo.setLeaseTermList(leaseTermMapper.getLeaseTerms(id));
}, threadPoolExecutor);
// 等待所有任务全部完成
try {
CompletableFuture.allOf(completableFuture,
graphVosFuture,
attrValueVosFuture,
facilityInfoFuture,
labelInfoFuture,
paymentTypeFuture,
leaseTermFuture).get();
} catch (Exception e) {
e.printStackTrace();
}
return resultVo;
}
}
总结:
通过异步编排实现多任务并行的场景的执行优化,手动配置线程池可以让我们根据具体业务,更好的设置线程池的参数。