【多线程】java多线程Completablefuture 详解【在spring cloud微服务之间调用,防止接口超时的应用】【未完成】
参考地址:https://www.jianshu.com/p/6f3ee90ab7d3
示例:
public static void main(String[] args) throws InterruptedException, ExecutionException { CompletableFuture<String> cf1 = new CompletableFuture<>(); new Thread(() -> { // 模拟执行耗时任务 System.out.println("task doing..."); try { Thread.sleep(3000); } catch (Exception e) { cf1.completeExceptionally(e); } // 告诉completableFuture任务已经完成 cf1.complete("3"); }).start(); CompletableFuture<String> cf2 = new CompletableFuture<>(); new Thread(() -> { // 模拟执行耗时任务 System.out.println("task doing..."); try { Thread.sleep(1000); } catch (Exception e) { cf2.completeExceptionally(e); } // 告诉completableFuture任务已经完成 cf2.complete("1"); }).start(); System.out.println(cf1.get()); System.out.println(cf2.get()); }
在spring cloud微服务中调用分别几个其他微服务中的服务接口,放置单线程进行调用,导致接口超时的问题,应用Completablefuture 解决:

@RestController public class TenTenementApiImpl implements ITenTenementApi{ @Autowired private SysTenementService sysTenementService; @Autowired private SysTenementConfigService sysTenementConfigService; @Autowired FeignTenBrandClient brandClient; @Autowired FeignTenDealerClient tenDealerClient; @Autowired FeignTenMemberClient tenMemberClient; @Autowired TenSecurityCodeCountClient tenSecurityCodeCountClient; /** * 租户首页 统计 * 企业概况 * * @return */ @Override public AjaxResult<TenStatisticalBean> tenStatistical() { AjaxResult<TenStatisticalBean> res = new AjaxResult<>(); TenementUser tenementUser = RequestData.TENEMENT_USER.get(); //获取租户的企业参数 获取 租户生成码 展示 内码/外码 SysTenementConfig sysTenementConfig = sysTenementConfigService.findByTenementId(tenementUser.getTenementId()); if (sysTenementConfig != null){ String tenJson = JSON.toJSONString(tenementUser); TenStatisticalBean bean = new TenStatisticalBean(); bean.setTid(tenementUser.getTenementId()); try { //商品统计,调用ms-goods服务 CompletableFuture<Integer> cf1 = new CompletableFuture<>(); new Thread(() -> { System.out.println("异步商品统计---->"); Integer goodsCount = 0; try { AjaxResult<Integer> goodsRes = brandClient.countGoodsByTid(tenJson); if (goodsRes.isSuccess()){ goodsCount = goodsRes.getObj(); } } catch (Exception e) { goodsCount = null; } // 告诉completableFuture任务已经完成 cf1.complete(goodsCount); }).start(); //经销商统计,调用ms-dealer服务 CompletableFuture<Integer> cf2 = new CompletableFuture<>(); new Thread(() -> { System.out.println("异步经销商统计---->"); Integer dealerCount = 0; try { AjaxResult<Integer> dealerRes = tenDealerClient.countDealerByTid(tenJson); if (dealerRes.isSuccess()){ dealerCount = dealerRes.getObj(); } } catch (Exception e) { dealerCount = null; } // 告诉completableFuture任务已经完成 cf2.complete(dealerCount); }).start(); //会员统计,调用ms-member服务 CompletableFuture<Integer> cf3 = new CompletableFuture<>(); new Thread(() -> { System.out.println("异步会员统计---->"); Integer memberCount = 0; try { AjaxResult<Integer> memberRes = tenMemberClient.countMemberByTid(tenJson); if (memberRes.isSuccess()){ memberCount = memberRes.getObj(); } } catch (Exception e) { memberCount = null; } // 告诉completableFuture任务已经完成 cf3.complete(memberCount); }).start(); //防伪码统计,调用ms-code服务 CompletableFuture<SecurityCodeCountBean> cf4 = new CompletableFuture<>(); new Thread(() -> { System.out.println("异步防伪码统计---->"); SecurityCodeCountBean securityCodeCount = new SecurityCodeCountBean(); try { AjaxResult<SecurityCodeCountBean> scRes = tenSecurityCodeCountClient.countScCodeByTid(tenJson); securityCodeCount = scRes.getObj(); if (scRes.isSuccess() && securityCodeCount != null){ } } catch (Exception e) { securityCodeCount = null; } // 告诉completableFuture任务已经完成 cf4.complete(securityCodeCount); }).start(); bean.setGoodsCount(cf1.get()); bean.setDealerCount(cf2.get()); bean.setMemberCount(cf3.get()); SecurityCodeCountBean securityCodeCount = cf4.get(); if (securityCodeCount != null){ //设置码号生成总数 bean.setScCodeCount(securityCodeCount.getScCode()); //设置历史库存 bean.setHistoryStock(securityCodeCount.getHistoryStock()); //即时库存 bean.setImmediateStock(securityCodeCount.getImmediateStock()); //经销商库存 bean.setDealerStock(securityCodeCount.getDealerStock()); //已出售 bean.setSellCount(securityCodeCount.getSellCount()); //在途 bean.setOnWayCount(securityCodeCount.getOnWayCount()); } res.initTrue(bean); } catch (InterruptedException e) { throw new LunaException(e.getMessage(), LunaResultBean.ERROR_BUSINESS); } catch (ExecutionException e) { throw new LunaException(e.getMessage(), LunaResultBean.ERROR_BUSINESS); } }else { res.initFalse("租户未配置企业参数",LunaResultBean.ERROR_BUSINESS); } return res; } }
附接收的实体:

public class TenStatisticalBean { private String tid;//租户ID private Integer goodsCount;//商品统计 private Integer dealerCount;//经销商统计 private Integer memberCount;//会员统计 private Long scCodeCount;//码号生成统计【此处及以下防伪码相关字段 都只展示 租户配置的产品码类型 内码量/外码量】 private Long historyStock;//历史库存 总共生成码 入 数据库的总量 private Long immediateStock;//即时库存 租户仓库 的库存数量 发货给经销商- 经销商退货给租户+ private Long onWayCount;//在途统计 private Long dealerStock;//经销商库存 经销商发货- 经销商收货+ 出售- 出售的退货+ private Long sellCount;//出售统计 所有出售的+ 退货给经销商- public Long getOnWayCount() { return onWayCount; } public void setOnWayCount(Long onWayCount) { this.onWayCount = onWayCount; } public String getTid() { return tid; } public void setTid(String tid) { this.tid = tid; } public Integer getGoodsCount() { return goodsCount; } public void setGoodsCount(Integer goodsCount) { this.goodsCount = goodsCount; } public Integer getDealerCount() { return dealerCount; } public void setDealerCount(Integer dealerCount) { this.dealerCount = dealerCount; } public Integer getMemberCount() { return memberCount; } public void setMemberCount(Integer memberCount) { this.memberCount = memberCount; } public Long getScCodeCount() { return scCodeCount; } public void setScCodeCount(Long scCodeCount) { this.scCodeCount = scCodeCount; } public Long getHistoryStock() { return historyStock; } public void setHistoryStock(Long historyStock) { this.historyStock = historyStock; } public Long getImmediateStock() { return immediateStock; } public void setImmediateStock(Long immediateStock) { this.immediateStock = immediateStock; } public Long getDealerStock() { return dealerStock; } public void setDealerStock(Long dealerStock) { this.dealerStock = dealerStock; } public Long getSellCount() { return sellCount; } public void setSellCount(Long sellCount) { this.sellCount = sellCount; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下