其他异步编程方法

Java5中新增了Future接口,用来描述异步计算的结果。虽然 Future 以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们的异步编程的初衷相违背,轮询的方式又会耗费无谓的 CPU 资源,而且也不能及时地得到计算结果。

CompletableFuture的优点支持事件回调(任务完成,任务异常等)由于它实现了Future接口,所以也可以用get()阻塞式的获取结果

支持串行执行、并行执行、合并异步结果、组合异步任务,即把上一个任务的输出作为下一个任务的输入

无需手工维护线程,语义清晰,代码优雅

使用方法

CompletableFuture的使用流程大致分为三步创建CompletableFuture对象

描述任务关系(串行,并行,汇聚)

处理异步计算结果

创建//比较特殊,入参就是返回值,返回值就是异步计算的结果

public static CompletableFuture completedFuture(U value)

//无返回值,使用默认线程池

public static CompletableFuture runAsync(Runnable runnable)

//无返回值,使用自定义线程池

public static CompletableFuture runAsync(Runnable runnable, Executor executor)

//有返回值,使用默认线程池

public static CompletableFuture supplyAsync(Supplier supplier)

//有返回值,使用自定义线程池

public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)

描述串行关系有Async的是异步方法//接收上一任务的输出并输出结果

CompletionStage thenApply(fn);

CompletionStage thenApplyAsync(fn);

//接收上一任务的输出,但不输出结果

CompletionStage thenAccept(consumer);

CompletionStage thenAcceptAsync(consumer);

//不接收输入,也不输出结果

CompletionStage thenRun(action);

CompletionStage thenRunAsync(action);

//和thenApply类似,类似map和flatmap的区别

CompletionStage thenCompose(fn);

CompletionStage thenComposeAsync(fn);

示例CompletableFuture.completedFuture("hello").thenApply(s -> {

System.out.println("任务1:"+Thread.currentThread().getId());

return s+" word";

}).thenApplyAsync(s->{

System.out.println("任务2:"+Thread.currentThread().getId());

return s+" !";

}).thenAccept(System.out::println);

System.out.println("主线程:"+Thread.currentThread().getId());

Thread.sleep(4000);

/*

输出结果

任务1:1

主线程:1

任务2:15

hello word !

*/

注意上面的代码,任务1是thenApply()同步方法,任务2是thenApplyAsync()异步方法。从输出结果可以看到,同步方法是在主线程执行的,而异步方法则丢到线程池执行。任务2虽然是异步方法,但由于是串行执行,它还是要等待任务1执行完毕才能执行。

描述AND汇聚关系//有Async的是异步方法

//接收上一任务的输出,并输出结果

CompletionStage thenCombine(other, fn);

CompletionStage thenCombineAsync(other, fn);

//接收上一任务的输出,但不输出结果

CompletionStage thenAcceptBoth(other, consumer);

CompletionStage thenAcceptBothAsync(other, consumer);

//不接收上一任务的输出,也不输出结果

CompletionStage runAfterBoth(other, action);

CompletionStage runAfterBothAsync(other, action);

示例

创建f1和f2两个异步任务,然后等待f1和f2都执行完毕,将结果相加后打印CompletableFuture f1=CompletableFuture.supplyAsync(()->"hello");

CompletableFuture f2=CompletableFuture.supplyAsync(()->"world");

f1.thenCombine(f2,(s, s2) -> s+" "+s2).thenAccept(System.out::println);

//输出hello world

描述OR汇聚关系//有Async的是异步方法

//接收上一任务的输出,并输出结果

CompletionStage applyToEither(other, fn);

CompletionStage applyToEitherAsync(other, fn);

//接收上一任务的输出,但不输出结果

CompletionStage acceptEither(other, consumer);

CompletionStage acceptEitherAsync(other, consumer);

//不接收上一任务的输出,也不输出结果

CompletionStage runAfterEither(other, action);

CompletionStage runAfterEitherAsync(other, action);

示例

创建两个异步任务,哪个任务先执行完就输出谁CompletableFuture f1 =

CompletableFuture.supplyAsync(()->{

int t = (int) (Math.random()*1000)+1000;

try {

Thread.sleep(t);

} catch (InterruptedException e) {

e.printStackTrace();

}

return String.valueOf(t);

}).whenCompleteAsync((s, throwable) -> System.out.println(s));

CompletableFuture f2 =

CompletableFuture.supplyAsync(()->{

int t = (int) (Math.random()*1000)+1000;

try {

Thread.sleep(t);

} catch (InterruptedException e) {

e.printStackTrace();

}

return String.valueOf(t);

}).whenCompleteAsync((s, throwable) -> System.out.println(s));

CompletableFuture f3 = f1.applyToEither(f2,s -> s);

System.out.println(f3.join());

Thread.sleep(2000);

事件回调//任务异常回调,有返回值,可以自己返回

CompletionStage exceptionally(fn);

//任务完成回调,有返回值,但这个返回值是异步任务的结果,我们不能返回

CompletionStage whenComplete(consumer);

CompletionStage whenCompleteAsync(consumer);

//任务完成回调,有返回值,可以自己返回

CompletionStage handle(fn);

CompletionStage handleAsync(fn);

示例CompletableFuture f0 =

CompletableFuture.supplyAsync(()->7/0).thenApply(r->r*10)

//放在exceptionally前面,可以获取到异步任务的结果,放在放在exceptionally后面,只能获取到exceptionally返回的结果

.whenComplete((integer, throwable) -> System.out.println(integer))

.exceptionally(t->{

t.printStackTrace();

//会覆盖异步任务的结果

return -1;

});

System.out.println(f0.join());

Thread.sleep(2000);

其他方法//接收多个CompletableFuture任务,等待全部任务执行完毕

public static CompletableFuture allOf(CompletableFuture>... cfs)

//接收多个CompletableFuture任务,等待任意一个任务执行完毕,并返回执行结果

public static CompletableFuture anyOf(CompletableFuture>... cfs)

java8异步任务,Java8 - CompletableFuture 异步编程类相关推荐

  1. java 并发 异步_Java并发 CompletableFuture异步编程的实现

    前面我们不止一次提到,用多线程优化性能,其实不过就是将串行操作变成并行操作.如果仔细观察,你还会发现在串行转换成并行的过程中,一定会涉及到异步化,例如下面的示例代码,现在是串行的,为了提升性能,我们得 ...

  2. c++ 异步下获取线程执行结果_异步编排(CompletableFuture异步调用)

    1.问题背景 问题:当查询接口较复杂时候,数据的获取都需要远程调用,必然需要花费更多的时间. 假如查询文章详情页面,需要如下标注的时间才能完成: 那么,用户需要4s后才能统计的数据.很显然是不能接受的 ...

  3. 多线程与并发 - Java 8 CompletableFuture 异步多线程

    1.一个示例回顾Future 一些业务场景我们需要使用多线程异步执行任务,加快任务执行速度. JDK5新增了Future接口,用于描述一个异步计算的结果. 虽然 Future 以及相关使用方法提供了异 ...

  4. Java之CompletableFuture异步、组合计算基本用法

    CompletableFuture是Java8新增的Api,该类实现了Future和ComplateStage两个接口,提供了强大的Future扩展功能,可以简化异步编程的复杂性,提供了函数编程的能力 ...

  5. Day140-142.尚品汇:AOP+Redis缓存+redssion分布式锁、CompletableFuture异步编排、首页三级分类展示、Nginx静态代理

    目录 Day08 一.获取商品详情 加入缓存 二.全局缓存:分布式锁与aop 整合 三.布隆过滤器 四.CompletableFuture 异步编排 jdk1.8 Day09 1. 将item 改为多 ...

  6. springboot异步和切面_Spring异步编程 你的@Async就真的异步吗?异步历险奇遇记

    引言有点长 前端的宝宝会用ajax,用异步编程到快乐的不行~ 我们java也有异步,用起来比他们还快乐~ 我们biaji一个注(gǒupí)解(gāoyào),也是快乐风男... 且看下面的栗子: 注 ...

  7. springboot异步和切面_Spring异步编程 | 你的@Async就真的异步吗 ☞ 异步历险奇遇记...

    引言有点长 前端的宝宝会用ajax,用异步编程到快乐的不行~ 我们java也有异步,用起来比他们还快乐~ 我们bia~ji~一个注(gǒupí)解(gāoyào),也是快乐风男... 且看下面的栗子: ...

  8. springboot异步和切面_Spring异步编程 | 你的@Async就真的异步吗?异步历险奇遇记

    Spring异步编程 | 你的@Async就真的异步吗?异步历险奇遇记 点击上方"java进阶架构师",选择右上角"置顶公众号" 20大进阶架构专题每日送达 引 ...

  9. 谷粒商城十五商品详情CompletableFuture异步编排

    多线程异步任务的问题 例如a,b,c三个异步任务,不是随机运行就可以,它们还有一定的关系,c需要等待a的返回结果,b不需要等待谁的结果. 当异步任务产生一些关系和顺序之后,我们要编排好它们的关系进行调 ...

最新文章

  1. %matplotlib inline %config InlineBackend.figure_format = “retina为了将图片嵌入notebook及提高分
  2. 【Java基础】关键字
  3. java窗体设置最小宽度_flex web Application设置最小高度和宽度。
  4. 【Homework】说出 == 和 equals 的区别
  5. 我的Go语言学习之旅六:做一个WIN的简单弹窗
  6. 1万块钱如何理财可以获得最高收益?
  7. [蓝桥杯2017初赛]跳蚱蜢-map标记+bfs+环形数组
  8. 深入理解Angular订阅者模式
  9. 压缩之后神经网络忘记了什么?Google研究员给出了答案
  10. PHP生成登录图片验证码
  11. ASP.NET的錯誤類型及錯誤處理方式
  12. poj 3279 poj 1753
  13. AWT_Swing_图片Icon
  14. 统一沟通-技巧-9-Lync 2010-Outlook 2010-自动配置-1-IT人员
  15. Python 日期计算:计算某日期前几天,后几天的日期,也可以计算小时,分钟之后的日期时间
  16. JavaSE基础——Object类中的常用方法
  17. ectouch微信支付,带微信H5支付
  18. xp此计算机无法连接到,XP系统无法连接到网络怎么办
  19. 木马 + 流氓软件 + 垃圾软件 玩死 Win 2000 pro~
  20. npm ERR! Error: tunneling socket could not be established的解决问题

热门文章

  1. [黑鹰,暗组,黑旋,红娘,死神
  2. SELECT 的用法
  3. Oracle数据库第二课2——PLSQL Developer使用教程及基础操作。
  4. 使用xpath定位元素,报Message: invalid argument: invalid locator
  5. 解决Git拉取代码时报错 Cloning into ‘h5functionpage4xwc.git~‘..fatal: protocol ‘?[200~http‘ is not supported
  6. CALL和RET指令
  7. JCMsuite应用:多核光子晶体光纤
  8. OpenCV36: BRIEF 二进制稳健独立的基本特征
  9. Anaconda中用pip安装本地包
  10. 【Visual Studio】Visual Studio更换背景图与其他快捷操作集合