假如我有一个订单相关的统计接口,需要返回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. Java开发环境配置大全

    Java开发环境配置 零章:JDK安装教程 壹章:Tomcat安装教程 贰章:IntelliJ IDEA安装教程 叁章:MySql安装教程 肆章:Maven安装教程 伍章:MongoDB安装教程 陆章 ...

  2. ORA-12514: 监听程序当前无法识别连接描述符中请求的服务

    /** 异常:ORA-12514: 监听程序当前无法识别连接描述符中请求的服务 * 背景:在很长一段时间都在连接远程开发库,曾偶尔有一次想要连接本地的库进行sql测试,发现连接失败,起初一直有无监听. ...

  3. 实战 MySQL 8.0.17 Clone Plugin(转)

    背景 很神奇,5.7.17 和 8.0.17,连续两个17小版本都让人眼前一亮.前者加入了组复制(Group Replication)功能,后者加入了克隆插件(Clone Plugin)功能.今天我们 ...

  4. 基于gin框架搭建的一个简单的web服务

    刚把go编程基础知识学习完了,学习的时间很短,可能还有的没有完全吸收.不过还是在项目中发现知识,然后在去回顾已学的知识,现在利用gin这个web框架做一个简单的CRUD操作. 1.Go Web框架的技 ...

  5. 项目Beta冲刺(团队)——05.28(6/7)

    项目Beta冲刺(团队)--05.28(6/7) 格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺(团队) 团队名称:为了交项目干杯 作业目标:记录Beta敏捷冲刺第6 ...

  6. SpringBoot中实现Spring容器中注入类型相同但名不同Bean

    @Bean(autowire = Autowire.BY_NAME,value = "kaptchaProducer") public Producer kaptchaProduc ...

  7. 牛客OI周赛10-普及组-A眼花缭乱的街市-(加速+二分)

    https://ac.nowcoder.com/acm/contest/901/A 很简单的一道题,全场只有20+AC,卡时间.新学了cin加速语法和数组二分查找的函数调用. 知道有个读写挂,可以加速 ...

  8. java之Matcher类详解

    在JDK 1.4中,Java增加了对正则表达式的支持. java与正则相关的工具主要在java.util.regex包中:此包中主要有两个类:Pattern.Matcher. Matcher  声明: ...

  9. 验证码破解 | Selenium模拟登陆12306

    12306官网登录的验证码破解比较简单,验证码是常规的点触类型验证码,使用超级鹰识别率比较高. 思路: (1)webdriver打开浏览器: (2)先对整个屏幕截屏,通过标签定位找到验证码图片,并定位 ...

  10. ubuntu 安装任何版本的Firefox

    https://ftp.mozilla.org/pub/firefox/releases/ 1.sudo gedit /usr/share/applications/firefox.desktop 2 ...