研发必会-异步编程利器之CompletableFuture含源码 中

微信公众号访问地址: 研发必会-异步编程利器之CompletableFuture(含源码 中)近期热推文章:1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;3、基于Redis的Geo实现附近商铺搜索(含源码)4、基于Redis实现关注、取关、...
研发必会-异步编程利器之CompletableFuture含源码 中
微信公众号访问地址: 研发必会-异步编程利器之CompletableFuture(含源码 中)

近期热推文章:

1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;

2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;

3、基于Redis的Geo实现附近商铺搜索(含源码)

4、基于Redis实现关注、取关、共同关注及消息推送(含源码)

5、SpringBoot整合多数据源,并支持动态新增与切换(详细教程)

6、基于Redis实现点赞及排行榜功能

7、研发必会-异步编程利器之CompletableFuture(上)

一、多任务组合回调

备注:源码获取方式在文底。

1.1、AND组合关系

thenCombine / thenAcceptBoth / runAfterBoth都表示:将两个CompletableFuture组合起来,只有这两个都正常执行完了,才会执行某个任务。也即:当任务一和任务二都完成再执行任务三(异步任务)。

区别在于:

1、runAfterBoth:不会把执行结果当做方法入参,且没有返回值。

2、thenAcceptBoth:会将两个任务的执行结果作为方法入参,传递到指定方法中,且无返回值。

3、thenCombine:会将两个任务的执行结果作为方法入参,传递到指定方法中,且有返回值。

代码案例:

运行结果:

1.2、OR组合关系

将两个CompletableFuture组合起来,只要其中一个执行完了,就会执行某个任务。(两个任务,只要有一个任务完成,就执行任务三)

区别在于:

1、runAfterEither:不会把执行结果当做方法入参,且没有返回值。

2、acceptEither: 会将已经执行完成的任务,作为方法入参,传递到指定方法中,且无返回值。

3、applyToEither:会将已经执行完成的任务,作为方法入参,传递到指定方法中,且有返回值。(个人推荐)

参考代码:

返回结果:

若将异步任务02中的Thread.sleep(600)改为300,将输出的结果为:

从结果中不难对比发现,任务03的参数是任务01和任务02中执行最快的返回结果。

注意:若把核心线程数量改为1,会是什么样的呢?

运行结果:

从上面看出,改为1就变成单线程执行了。

1.3、多任务组合(allOf\anyOf)

1.allOf:等待所有任务都执行完成后,才会执行 allOf 返回的CompletableFuture。如果任意一个任务异常,allOf的CompletableFuture,执行get方法,会抛出异常。(等待所有任务完成才会执行)

2.anyOf:任意一个任务执行完,就执行anyOf返回的CompletableFuture。如果执行的任务异常,anyOf的CompletableFuture,执行get方法,会抛出异常。(只要有一个任务完成)

参考案例:

结果返回:

从结果中看出:等待所有任务都执行完成后,才会执行 allOf 返回的CompletableFuture。

同理anyOf,只需要调整代码:

运行结果:

1.4、thenCompose

thenCompose方法会在某个任务执行完成后,将该任务的执行结果,作为方法入参,去执行指定的方法。该方法会返回一个新的CompletableFuture实例。

1、如果该CompletableFuture实例的result不为null,则返回一个基于该result新的CompletableFuture实例;

2、如果该CompletableFuture实例为null,然后就执行这个新任务。

代码案例:

结果:

二、使用注意点

CompletableFuture 使异步编程更加便利的、代码更加优雅的同时,也要关注使用的一些注意点。

2.1、Future需要获取返回值,才能获取异常信息

代码案例:

输出结果:

Future需要获取返回值(res01.get()),才能获取到异常信息。如果不加 get()/join()方法,看不到异常信息。使用的时候,注意一下,考虑是否加try…catch…或者使用exceptionally方法。

若改成exceptionally方法,无需get或join也可以捕获异常信息:

结果:

2.2、CompletableFuture的get()方法是阻塞的

CompletableFuture的get()方法是阻塞的,如果使用它来获取异步调用的返回值,需要添加超时时间。

推荐使用:

2.3、建议使用自定义线程池,不要使用默认的

CompletableFuture代码中使用了默认的线程池,处理的线程个数是电脑CPU核数-1。在大量请求过来的时候,处理逻辑复杂的话,响应会很慢。一般建议使用自定义线程池,优化线程池配置参数。

参考案例:

但是如果线程池拒绝策略是DiscardPolicy或者DiscardOldestPolicy,当线程池饱和时,会直接丢弃任务,不会抛弃异常。因此建议,CompletableFuture线程池策略最好使用AbortPolicy,然后耗时的异步线程,做好线程池隔离。

说明:

AbortPolicy(默认):直接抛弃

CallerRunsPolicy:用调用者的线程执行任务

DiscardOldestPolicy:抛弃队列中最久的任务

DiscardPolicy:抛弃当前任务。

三、源码获取方式

更多优秀文章,请关注个人微信公众号或搜索“程序猿小杨”查阅。然后回复:源码,可以获取对应的源码,开箱即可使用。

如果大家对相关文章感兴趣,可以关注微信公众号"程序猿小杨",会持续更新优秀文章!欢迎大家 分享、收藏、点赞、在看,您的支持就是我坚持下去的最大动力!谢谢!

参考网站:

blog.csdn.net/ThinkWon/...

mp.weixin.qq.com/s/shjA...2024-08-21
mengvlog 阅读 145 次 更新于 2025-09-09 03:25:48 我来答关注问题0
  •  誉祥祥知识 深入理解Rust Tokio Select:异步编程的多路复用利器

    Tokio Select采用了公平调度策略。这意味着如果多个分支同时准备就绪,Select会随机选择一个分支执行,而不是总是选择第一个分支。这有助于避免某些分支被饿死的情况,确保所有分支都有机会被选中执行。动态分支 Select支持动态数量的分支。这意味着我们可以使用循环来动态生成Select的分支,这在处理未知数量的...

  •  猪八戒网 PHP框架的PHP开发框架

    快速开发、部署、学习必备利器。KPHP即(kphp开源框架)是为了提高PHP开发效率而研发php开源框架,其核心简单精炼,代码安全并易于理解,功能更符合php学习开发的的需要,而且易于学习不改变程序员的开发习惯。ZendFramework在开发社区中有大量的追随者,它致力于Web2.0风格的程序。因为它众多的追随者组成的活跃用户开发的扩展支...

  •  长沙新华电脑学院 只学Python可以找什么样的工作

    网络爬虫作为数据采集的利器,在大数据时代作为数据的源头,十分有用武之地。利用Python可以更快的提升对数据抓取的精准程度和速度,是数据分析师的福祉,通过网络爬虫,让BOSS再也不用担心你没有数据。做爬虫工程师的的薪资为20K起,当然,因为大数据,薪资也将一路上扬。四、Python web全栈工程师 全栈工...

  •  琳琳3569781 java培训的学费价格大约是多少

    据了解,现在的编程培训学费一般在15000—20000之间,教学质量有好有坏,俗话说便宜无好货,但是也不能以偏概全,也有实惠又实在的培训机构存在,也不是说学费越贵的教学质量一定好,但是贵也一定有它的道理。不了解你的个人情况(学历,专业,年龄,是否有基础,之前的工作经验,家庭经济情况),这些因...

檬味博客在线解答立即免费咨询

编程相关话题

Copyright © 2023 WWW.MENGVLOG.COM - 檬味博客
返回顶部