使用CompletableFuture实现异步编程
在开发中会碰到一种场景,如下
Object result1 = service1.func1();//执行80ms
Object result2 =service2.func2();//执行50ms service3.func3(result1,result2);
func3()需要等待func1和func2的执行结果。总共需要等待130ms.如果能够让func1和func2同时执行,那么最少的等待时间将会是80ms.
下面使用CompletableFuture来实现。
JDK1.8才新加入的一个实现类CompletableFuture
,实现了Future<T>
, CompletionStage<T>
两个接口。
定义任务类
这里定义了一个方法findUser,它的返回值是CompletableFuture<String>,用来模拟远程调用。
当执行结果是正常时,通过
public boolean complete(T value)
返回结果。
当执行异常时,如果想向调用者返回异常,通过
public boolean completeExceptionally(Throwable ex)
返回异常。
class TaskService{ public CompletableFuture<String> findUser(){
CompletableFuture<String> future = new CompletableFuture();
//模仿远程调用线程
new Thread(){ @Override
public void run() { String result = null;
System.out.println("任务开始执行....");
try{
Thread.sleep(3000);
//模仿RPC远程调用
result = rpcRequest(true); System.out.println("任务执行结束...."); }
catch(Exception ex){
future.completeExceptionally(ex);
}
future.complete(result);
}
}.start();
直接返回future.
return future;
} /**
*功能描述
* @author lgj
* @Description 模仿RPC远程调用
* @date 4/29/19
* @param: flag true:返回正常结果 false:抛出异常
*
* @return:
*
*/
public String rpcRequest(boolean flag){
String result = null;
if(flag){
result = "libai";
}
else {
throw new NullPointerException();
}
return result;
} }
主线程调用
public class CompletableFutureDemo { public static void main(String args[]){ TaskService service = new TaskService(); CompletableFuture<String> future = service.findUser(); future.whenComplete((t,u)->{ if(u != null){
System.out.println("异步调用发生异常:" + u);
}
else {
System.out.println("异步调用执行正常: " + t);
} }); System.out.println("主线程任务执行完毕"); }
}
主线程通过whenComplete来回调结果。这里需要通过lambada 表达式来获取结果
public CompletableFuture<T> whenComplete(
BiConsumer<? super T, ? super Throwable> action) {
return uniWhenCompleteStage(null, action);
}
当结果正常时
任务开始执行....
主线程任务执行完毕
任务执行结束....
异步调用执行正常: libai
当调用发生异常时
任务开始执行....
主线程任务执行完毕
异步调用发生异常:java.lang.NullPointerException
以上,便实现了异步调用。
目前,dubbo-2.7.0+便是使用CompletableFuture来实现rpc异步调用。
使用CompletableFuture实现异步编程的更多相关文章
- 从CompletableFuture到异步编程设计
从CompletableFuture到异步编程设计,笔者就分为2部分来分享CompletableFuture异步编程设计,前半部分总结下CompletableFuture使用实践,后半部分分享下Com ...
- Java 8 (10) CompletableFuture:组合式异步编程
随着多核处理器的出现,提升应用程序的处理速度最有效的方式就是可以编写出发挥多核能力的软件,我们已经可以通过切分大型的任务,让每个子任务并行运行,使用线程的方式,分支/合并框架(java 7) 和并行流 ...
- 异步编程CompletableFuture实现高并发系统优化之请求合并
先说场景: 根据Redis官网介绍,单机版Redis的读写性能是12万/秒,批量处理可以达到70万/秒.不管是缓存或者是数据库,都有批量处理的功能.当我们的系统达到瓶颈的时候,我们考虑充分的压榨缓存和 ...
- Java8函数之旅 (八) - 组合式异步编程
前言 随着多核处理器的出现,如何轻松高效的进行异步编程变得愈发重要,我们看看在java8之前,使用java语言完成异步编程有哪些方案. JAVA8之前的异步编程 继承Thead类,重写run方法 实现 ...
- 有了 CompletableFuture,使得异步编程没有那么难了!
本文导读: 业务需求场景介绍 技术设计方案思考 Future 设计模式实战 CompletableFuture 模式实战 CompletableFuture 生产建议 CompletableFutur ...
- 编程老司机带你玩转 CompletableFuture 异步编程
本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...
- 搞定 CompletableFuture,并发异步编程和编写串行程序还有什么区别?你们要的多图长文
你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...
- 异步编程CompletableFuture
多线程优化性能,串行操作并行化 串行操作 // 以下2个都是耗时操作 doBizA(); doBizB(); 修改变为并行化 new Thread(() -> doBizA()).start() ...
- 带你玩转CompletableFuture异步编程
前言 最近在忙生活的第一个OKR,这个等等后面具体聊聊,今天开始恢复每周一篇原创,感谢小伙伴的不离不弃.这篇文章也是最近在Code Review的时候,看到的大家代码,想整体推下大家异步编程的思想,由 ...
随机推荐
- AngularJS - 使用RequireJS还是Browserify?
http://www.html-js.com/article/2126 AngularJS - 使用RequireJS还是Browserify? AngularJS之所以吸引了很多开发者的关注,很大一 ...
- spring cloud 入门系列五:使用Feign 实现声明式服务调用
一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ...
- JDK 源码分析(4)—— HashMap/LinkedHashMap/Hashtable
JDK 源码分析(4)-- HashMap/LinkedHashMap/Hashtable HashMap HashMap采用的是哈希算法+链表冲突解决,table的大小永远为2次幂,因为在初始化的时 ...
- php使用http_build_query,parse_url,parse_str创建与解析url详解
1.http_build_query string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $ ...
- html块级元素与行内元素
1.关于行内元素和快元素的说明: 根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display ...
- htmlparser 学习
htmlparser 学习系列 htmlparser 使用法使用与详解
- 使用webpack打包后的vue项目如何运行(express)
我们知道使用webpack打包vue项目后会生成一个dist文件夹,dist文件夹下有html文件和其他css.js以及图片等,那么打包后的文件该如何正确运行呢? 倘若直接打开html文件,会报如下错 ...
- 条件随机场CRF(二) 前向后向算法评估标记序列概率
条件随机场CRF(一)从随机场到线性链条件随机场 条件随机场CRF(二) 前向后向算法评估标记序列概率 条件随机场CRF(三) 模型学习与维特比算法解码 在条件随机场CRF(一)中我们总结了CRF的模 ...
- Java开源生鲜电商平台-支付模块的设计与架构(源码可下载)
Java开源生鲜电商平台-支付模块的设计与架构(源码可下载) 开源生鲜电商平台支付目前支持支付宝与微信.针对的是APP端(android or IOS) 1. 数据库表设计. 说明:无论是支付宝还 ...
- ThreadPoolExecutor 学习笔记
线程池的奥义 在开发程序的过程中,很多时候我们会遇到遇到批量执行任务的场景,当各个具体任务之间互相独立并不依赖其他任务的时候,我们会考虑使用并发的方式,将各个任务分散到不同的线程中进行执行来提高任务的 ...