【JAVA高级】接口响应慢?用 CompletableFuture 优化。
这里跟大家讲解如何利用CompletableFuture优化项目代码,使性能更佳
public void inCallBackERP(InERPCallBackDto inCallBackERPDto) throws ExecutionException, InterruptedException {//入库回调ERPCompletableFuture<Void> erpCallbackFuture = CompletableFuture.runAsync(() -> {WmsPutawayShelfTask putawayTask = putawayShelfTaskService.selectById(inCallBackERPDto.getPutawayTaskId());if(ObjectUtil.isEmpty(putawayTask)){throw new ServiceException(StringUtils.format("未找到任务id为{}的上架任务", inCallBackERPDto.getPutawayTaskId()));}/** 入库反馈-天囤ERP **/if(ThreeErpCommonEnum.SYN_WAY.TT_ERP.getCode().equals(putawayTask.getSynWay())){inCallbackHandler.inCallback(inCallBackERPDto);}/** 入库反馈-三方ERP **/if(ThreeErpCommonEnum.SYN_WAY.THREE_ERP.getCode().equals(putawayTask.getSynWay())){WmsPurchaseOrderForm orderForm = commonOrderHandler.getInOrderFormByOrderFormId(putawayTask.getOrderFormId());if(ObjectUtil.isNotEmpty(orderForm)){if(WmsInOrderEnum.ORDER_FORM_STATUS_YRK.getCode().equals(orderForm.getStatus())){//已入库threeErpCallBackHandler.inOrderCallBack(buildInFeedBack(orderForm));}}}}, threadPoolExecutor);/** 线程执行异常时可放开此行查看日志 **///erpCallbackFuture.get();}
异步编程
举个例子:用户登录成功,需要返回前端用户角色,菜单权限,个人信息,用户余额,积分情况等。正常逻辑是依次查询不同表,得到对应的数据封装返回给前端,代码如下:
@Test
public void login(Long userId){log.info("开始查询用户全部信息---串行!");// 查询用户角色信息getUserRole(userId);// 查询用户菜单信息getUserMenu(userId);// 查询用户余额信息getUserAmount(userId);// 查询用户积分信息getUserIntegral(userId);log.info("封装用户信息返回给前端!");
}
假如查询用户角色,用户菜单,用户余额,用户积分分别耗时500,200,200,100毫秒,则登录接口耗时为1秒。如果采用异步(多线程并行)形式,则登录接口耗时以单个查询最慢的任务为主,为查询用户角色信息500毫秒。相当于登录接口性能提升一倍!查询任务越多,则其性能提升越大!
代码演示(串行):
@Test
public void login() throws InterruptedException {long startTime = System.currentTimeMillis();log.info("开始查询用户全部信息!");log.info("开始查询用户角色信息!");Thread.sleep(500);String role = "管理员";log.info("开始查询用户菜单信息!");Thread.sleep(200);String menu = "首页,账户管理,积分管理";log.info("开始查询查询用户余额信息!");Thread.sleep(200);Integer amount = 1999;log.info("开始查询查询查询用户积分信息!");Thread.sleep(100);Integer integral = 1015;log.info("封装用户信息返回给前端!");log.info("查询用户全部信息总耗时:" + (System.currentTimeMillis() - startTime) / 1000 + "秒");
}
耗时为1秒!
代码演示(异步):
@Test
public void asyncLogin() {long startTime = System.currentTimeMillis();log.info("开始查询用户角色信息!");CompletableFuture<Map<String, Object>> roleFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}Map<String, Object> roleMap = new HashMap<String, Object>();roleMap.put("role", "管理员");long endTime = System.currentTimeMillis();log.info("查询用户角色信息耗时:" + (endTime - startTime) +