加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长资讯 > 动态 > 正文

异步编程 CompletableFuture 全解析

发布时间:2021-04-08 13:57:09 所属栏目:动态 来源:互联网
导读:Future 提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们异步编程的初衷相违背,轮询的方式又会耗费无谓的 CPU 资源,而且也不能及时的获取结果。 当然,很多其他的语言采用回调

 Future 提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们异步编程的初衷相违背,轮询的方式又会耗费无谓的 CPU 资源,而且也不能及时的获取结果。

当然,很多其他的语言采用回调的方式来实现异步编程,比如 Node.js;Java 的一些框架,比如 Netty,Google Guava 也扩展了 Future 接口,提供了很多回调的机制,封装了工具类,辅助异步编程开发。

Java 作为老牌编程语言,自然也不会落伍。在 Java 8 中,新增了一个包含 50 多个方法的类:CompletableFuture,提供了非常强大的 Future 扩展功能,可以帮助我们简化异步编程的复杂性,提供函数式编程的能力。

四、CompletableFuture 类功能概览

如下图是 CompletableFuture 实现的接口:它实现了 Future 接口,拥有 Future 所有的特性,比如可以使用 get() 方法获取返回值等;还实现了 CompletionStage 接口,这个接口有超过 40 个方法,功能太丰富了,它主要是为了编排任务的工作流。

我们可以把工作流和工作流之间的关系分类为三种:串行关系,并行关系,汇聚关系。上述四个方法,都是提交任务的,runAsync 方法需要传入一个实现了 Runnable 接口的方法,supplyAsync 需要传入一个实现了 Supplier 接口的方法,实现 get 方法,返回一个值。

(1)run 和 supply 的区别

run 就是执行一个方法,没有返回值,supply 执行一个方法,有返回值。

(2)一个参数和两个参数的区别

第二个参数是线程池,如果没有传,则使用自带的 ForkJoinPool.commonPool() 作为线程池,这个线程池默认创建的线程数是 CPU 的核数(也可以通过 JVM option:-Djava.util.concurrent.ForkJoinPool.common.parallelism 来设置 ForkJoinPool 线程池的线程数)

2、串行关系 api

这些 api 之间主要是能否获得前一个任务的返回值与自己是否有返回值的区别。 thenApply 一起的还有 thenAccept 和 thenRun,thenAccept 能获得到前一个任务的返回值,但是自身没有返回值;thenRun 不能获得前一个任务的返回值,自身也没有返回值。

(2)thenApply 和 thenApplyAsync 的区别

这两个方法的区别,在于谁去执行任务。如果使用 thenApplyAsync,那么执行的线程是从 ForkJoinPool.commonPool() 或者自己定义的线程池中取线程去执行。如果使用 thenApply,又分两种情况,如果 supplyAsync 方法执行速度特别快,那么 thenApply 任务就使用主线程执行,如果 supplyAsync 执行速度特别慢,就是和 supplyAsync 执行线程一样。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读