假如我有一个订单相关的统计接口,需要返回3样数据:今日订单数、今日交易额、总交易额。

一般的我们的做法是串行调用3个函数,把调用返回的结果返回给调用者,这3次调用时串行执行的,如果每个调用耗时1秒的话,3次调用总耗时就是3秒。

这种做法效率非常低,因为3次调用之间无所谓先后顺序,所以采用并行执行效率会更好。比如使用线程池ExecutorService实现异步调用。

其实Java8提供了一个非常牛逼的CompletableFuture类,也可以实现异步化:

 import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; @Slf4j
@Service
public class OrderService { /**
* 今日订单数
*
* @return
*/
public CompletableFuture<String> todayOrderCount() {
return CompletableFuture.supplyAsync(() -> this.getTodayOrderCount());
} public CompletableFuture<String> todayTurnover() {
return CompletableFuture.supplyAsync(() -> this.getTodayTurnover());
} public CompletableFuture<String> totalTurnover() {
return CompletableFuture.supplyAsync(() -> this.getTotalTurnover());
} private String getTodayOrderCount() {
System.out.println(">>>>>>> 查询今日订单数:" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "50";
} /**
* 今日交易额
*
* @return
*/
private String getTodayTurnover() {
System.out.println(">>>>>>> 查询今日交易额:" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "200";
} /**
* 总交易额
*
* @return
*/
private String getTotalTurnover() {
System.out.println(">>>>>>> 查询总交易额:" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "800";
}
}
 import com.alibaba.fastjson.JSONObject;
import com.example.sb.service.test.impl.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.CompletableFuture; @Slf4j
@RestController
@RequestMapping("/order")
public class OrderController { @Autowired
private OrderService orderService; @GetMapping("/report")
public JSONObject report() {
long start = System.currentTimeMillis();
JSONObject json = orderReport();
System.out.println("耗时:" + (System.currentTimeMillis() - start));
return json;
} private JSONObject orderReport() {
CompletableFuture<String> todayOrderCountFuture = orderService.todayOrderCount();
CompletableFuture<String> todayTurnoverFuture = orderService.todayTurnover();
CompletableFuture<String> totalTurnoverFuture = orderService.totalTurnover(); JSONObject json = new JSONObject(); todayOrderCountFuture.whenComplete((v, t) -> {
json.put("todayOrderCountFuture", v);
});
todayTurnoverFuture.whenComplete((v, t) -> {
json.put("todayTurnoverFuture", v);
});
totalTurnoverFuture.whenComplete((v, t) -> {
json.put("totalTurnoverFuture", v);
}); CompletableFuture.allOf(todayOrderCountFuture, todayTurnoverFuture, totalTurnoverFuture)
.thenRun(() -> System.out.println("完成!!!!"))
.join();
return json;
}
}

浏览器访问:http://localhost:8080/order/report 执行结果截图如下:

因为每个OrderService的调用模拟都是耗时1秒,3个调用并行执行,最终耗时自然也是1秒。

使用CompletableFuture实现业务服务的异步调用实战代码的更多相关文章

  1. ArcGIS Runtime SDK for Android开发之调用GP服务(异步调用)

    一.背景说明 通过调用GP服务,Android客户端也能实现专业的.复杂的GIS分析处理功能,从而增加应用的实用价值. ArcGIS Server发布的GP服务,分为同步和异步两种类型,一般执行步骤较 ...

  2. 通讯服务类API调用的代码示例合集:短信服务、手机号归属地查询、电信基站查询等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 短信服务:通知类和验证码短信,全国三网合一通道,5秒内到达,费用低 ...

  3. 出行服务类API调用的代码示例合集:长途汽车查询、车型大全、火车票查询等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 长途汽车查询:全国主要城市的长途汽车时刻查询,汽车站查询 车型大全 ...

  4. Dubbo中CompletableFuture异步调用

    使用Future实现异步调用,对于无需获取返回值的操作来说不存在问题,但消费者若需要获取到最终的异步执行结果,则会出现问题:消费者在使用Future的get()方法获取返回值时被阻塞.为了解决这个问题 ...

  5. WCF初探-11:WCF客户端异步调用服务

    前言: 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的.有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码 ...

  6. mvc路由引起异步调用web服务的问题

    从一篇blog得知使用脚本可以异步调用Web服务,觉得很新鲜,因为自己很少用到Web服务,所以决定写一写看看什么效果. 首先在UI项目(我使用的是MVC4.0)里创建一个Web服务. 添加Web服务后 ...

  7. 使用 ajax 异步调用数据

    ajax 脚本 <script type="text/javascript" > function show(page) { var xmlhttp; try { xm ...

  8. 006-优化web请求二-应用缓存、异步调用【Future、ListenableFuture、CompletableFuture】、ETag、WebSocket【SockJS、Stomp】

    四.应用缓存 使用spring应用缓存.使用方式:使用@EnableCache注解激活Spring的缓存功能,需要创建一个CacheManager来处理缓存.如使用一个内存缓存示例 package c ...

  9. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

随机推荐

  1. SQL SERVER-查看内存使用情况

    --使用内存的各对象 SELECT type, sum(virtual_memory_reserved_kb) as VM_Reserved, sum(virtual_memory_committed ...

  2. H3C 无线交换机的数据转发原理

  3. sparkstreaming写入hbase表中总结

    执行spark代码插入数据到hbase表中去的时候,遇到的错误 1. 缺少hadoop-mapreduce-client-core-2.5.1.jar包 错误:java.lang.ClassNotFo ...

  4. 调用python脚本报错/usr/bin/env: python : No such file or directory

    一.调用python脚本报错 /usr/bin/env: python: No such file or directory 二.解决方法 原因是在windows上编写的脚本,使用dos2unix对脚 ...

  5. Win10-无法启动虚拟机

    环境:Win10 - 1903 Q1:安装使用Hyper-V后,安装Virtual box新建VM,无法启动 A1:卸载Hyper-V(非必须) 管理员运行ps/cmd   bcdedit /set  ...

  6. 项目Beta冲刺(团队) —— 总结

    所属课程 软件工程1916|W(福州大学) 作业要求 Beta冲刺--总结篇 团队名称 待就业六人组 后端源码 Github地址 APP源码 Github地址 在线评审表 腾讯文档地址 Beta版本A ...

  7. wordpress角色权限汇总

    我们在用wordpress开发的时候有时候需要设置不同的用户组及权限,具体有哪些角色权限呢?随ytkah一起来看看吧.WordPress使用了角色的概念,旨在让站点所有者能够控制用户在站点中可以做什么 ...

  8. JSE,JEE,JME三者之间有什么区别

    JAVA是一种面向对象语言由SUN公司出品 J针对不同的使用方向规划出J2SE,J2EE,J2ME三个版本 J2SE 指标准版一般用于用户学习JAVA语言的基础也是使用其他两个版本的基础主要用于编写C ...

  9. SuperSocket

    1.目前稳定版是 v1.6: 2.轻量级.可扩展.Socket应用程序框架: 3.你可以用来开发Socket服务端应用,不用关心如何使用Socket.如何维护Socket连接和Socket如何工作. ...

  10. 原手下一名98年的java离职了

    原手下一名98年的java离职了,回家考试要2年. 系统做的还算凑合,毕竟年龄在这. 需要改善的地方我会放到自己的项目管理工具中去改善. 离职前他一直跟我说微服务的启动是用docker,也感谢他,我们 ...