在开发中会碰到一种场景,如下

  1. Object result1 = service1.func1();//执行80ms
  2. Object result2 =service2.func2();//执行50ms
  3.  
  4. 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)

返回异常。

  1. class TaskService{
  2.  
  3. public CompletableFuture<String> findUser(){
  4. CompletableFuture<String> future = new CompletableFuture();
  5.      //模仿远程调用线程
  6. new Thread(){
  7.  
  8. @Override
  9. public void run() {
  10.  
  11. String result = null;
  12. System.out.println("任务开始执行....");
  13. try{
  14. Thread.sleep(3000);
  15. //模仿RPC远程调用
  16. result = rpcRequest(true);
  17.  
  18. System.out.println("任务执行结束....");
  19.  
  20. }
  21. catch(Exception ex){
  22. future.completeExceptionally(ex);
  23. }
  24. future.complete(result);
  25. }
  26. }.start();
  27.      直接返回future.
  28. return future;
  29. }
  30.  
  31. /**
  32. *功能描述
  33. * @author lgj
  34. * @Description 模仿RPC远程调用
  35. * @date 4/29/19
  36. * @param: flag   true:返回正常结果 false:抛出异常
  37. *    
  38. * @return:
  39. *
  40. */
  41. public String rpcRequest(boolean flag){
  42. String result = null;
  43. if(flag){
  44. result = "libai";
  45. }
  46. else {
  47. throw new NullPointerException();
  48. }
  49. return result;
  50. }
  51.  
  52. }     

主线程调用

  1. public class CompletableFutureDemo {
  2.  
  3. public static void main(String args[]){
  4.  
  5. TaskService service = new TaskService();
  6.  
  7. CompletableFuture<String> future = service.findUser();
  8.  
  9. future.whenComplete((t,u)->{
  10.  
  11. if(u != null){
  12. System.out.println("异步调用发生异常:" + u);
  13. }
  14. else {
  15. System.out.println("异步调用执行正常: " + t);
  16. }
  17.  
  18. });
  19.  
  20. System.out.println("主线程任务执行完毕");
  21.  
  22. }
  23. }

主线程通过whenComplete来回调结果。这里需要通过lambada 表达式来获取结果

  1. public CompletableFuture<T> whenComplete(
  2. BiConsumer<? super T, ? super Throwable> action) {
  3. return uniWhenCompleteStage(null, action);
  4. }

当结果正常时

  1. 任务开始执行....
  2. 主线程任务执行完毕
  3. 任务执行结束....
  4. 异步调用执行正常: libai

当调用发生异常时

  1. 任务开始执行....
  2. 主线程任务执行完毕
  3. 异步调用发生异常:java.lang.NullPointerException

以上,便实现了异步调用。

目前,dubbo-2.7.0+便是使用CompletableFuture来实现rpc异步调用。

使用CompletableFuture实现异步编程的更多相关文章

  1. 从CompletableFuture到异步编程设计

    从CompletableFuture到异步编程设计,笔者就分为2部分来分享CompletableFuture异步编程设计,前半部分总结下CompletableFuture使用实践,后半部分分享下Com ...

  2. Java 8 (10) CompletableFuture:组合式异步编程

    随着多核处理器的出现,提升应用程序的处理速度最有效的方式就是可以编写出发挥多核能力的软件,我们已经可以通过切分大型的任务,让每个子任务并行运行,使用线程的方式,分支/合并框架(java 7) 和并行流 ...

  3. 异步编程CompletableFuture实现高并发系统优化之请求合并

    先说场景: 根据Redis官网介绍,单机版Redis的读写性能是12万/秒,批量处理可以达到70万/秒.不管是缓存或者是数据库,都有批量处理的功能.当我们的系统达到瓶颈的时候,我们考虑充分的压榨缓存和 ...

  4. Java8函数之旅 (八) - 组合式异步编程

    前言 随着多核处理器的出现,如何轻松高效的进行异步编程变得愈发重要,我们看看在java8之前,使用java语言完成异步编程有哪些方案. JAVA8之前的异步编程 继承Thead类,重写run方法 实现 ...

  5. 有了 CompletableFuture,使得异步编程没有那么难了!

    本文导读: 业务需求场景介绍 技术设计方案思考 Future 设计模式实战 CompletableFuture 模式实战 CompletableFuture 生产建议 CompletableFutur ...

  6. 编程老司机带你玩转 CompletableFuture 异步编程

    本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...

  7. 搞定 CompletableFuture,并发异步编程和编写串行程序还有什么区别?你们要的多图长文

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  8. 异步编程CompletableFuture

    多线程优化性能,串行操作并行化 串行操作 // 以下2个都是耗时操作 doBizA(); doBizB(); 修改变为并行化 new Thread(() -> doBizA()).start() ...

  9. 带你玩转CompletableFuture异步编程

    前言 最近在忙生活的第一个OKR,这个等等后面具体聊聊,今天开始恢复每周一篇原创,感谢小伙伴的不离不弃.这篇文章也是最近在Code Review的时候,看到的大家代码,想整体推下大家异步编程的思想,由 ...

随机推荐

  1. LruCache的使用及原理

    采用LRU算法实现的话就是将最老的数据删掉.利用LRU缓存,我们能够提高系统的性能.   一,是它本身已经实现了按照访问顺序的存储,也就是说,最近读取的会放在最前面,最不常读取的会放在最后(当然,它也 ...

  2. Java虚拟机-类文件

    代码编译的结果从本地机器码转换为字节码,是存储格式发展的一小步,却是编程语言发展的一大步.计算机只认识0和1,所以我们的程序需要经过编译器翻译成由0和1组成的二进制格式才能由计算机执行.经过技术的发展 ...

  3. OCR智能识别身份信息

    本人研究了两款OCR智能识别的API,下面做详解! 第一款是百度云的OCR识别,填写配置信息,每天有五百次免费的识别次数,适合中小型客户流量可以使用.API文档:http://ai.baidu.com ...

  4. EF Linq中的左连接Left Join查询

    linq中的join是inner join内连接,就是当两个表中有一个表对应的数据没有的时候那个关联就不成立. 比如表A B的数据如下 from a in A join b in B on a.BId ...

  5. .net捕捉全局未处理异常的3种方式

    前言: 我们在实际项目开发中,经常会遇到一些不可预见的异常产生,有的异常在程序运行时就对其进行处理(try)但是,有的程序不需要每一个地方都用try进行处理,那么针对这种情况,可以参照下面的方式,实现 ...

  6. MapReduce的架构及原理

    MapReduce是一种分布式计算模型,是Hadoop的主要组成之一,承担大批量数据的计算功能.MapReduce分为两个阶段:Map和Reduce. 一.MapReduce的架构演变 客户端向Job ...

  7. Egg Dropping Puzzle问题的分析

    首先,基本问题是这样:You are given two eggs, and access to a 100-storey building. The aim is to find out the h ...

  8. TCP连接和 time_wait、close_waite

    TCP连接和 time_wait.close_waite tags:time_wait close_waite RST TCP 引言:前两天朋友公司的服务器垮掉了,最后查出的原因是发现大量的time_ ...

  9. PAT1035: Password

    1035. Password (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To prepare f ...

  10. InnoDB存储引擎结构介绍

    Ⅰ.InnoDB发展史 时间 事件 备注 1995 由Heikki Tuuri创建Innobase Oy公司,开发InnoDB存储引擎 Innobase开始做的是数据库,希望卖掉该公司 1996 My ...