研发必会-异步编程利器之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 阅读 7 次 更新于 2025-07-20 21:30:29 我来答关注问题0
  • 7、研发必会-异步编程利器之CompletableFuture(上)一、多任务组合回调 备注:源码获取方式在文底。1.1、AND组合关系 thenCombine / thenAcceptBoth / runAfterBoth都表示:将两个CompletableFuture组合起来,只有这两个都正常执行完了,才会执行某个任务。也即:当任务一和任务二都完成再执行任务三(异步任...

  • CompletableFuture是Java中用于异步编程的强大工具,它解决了传统Future接口的不足,提供了更灵活、高效的异步任务管理方式。以下是关于CompletableFuture的主要特点和优势:创建与结果获取:多种创建方式:CompletableFuture提供了supplyAsync、runAsync等静态方法,用于方便地创建异步任务。灵活的结果获取:除了传统的g...

  •  文暄生活科普 异步编程利器:CompletableFuture深度解析

    执行流程包括创建CompletableFuture对象、定义异步任务、启动执行、任务完成、注册回调方法、组合异步任务、处理异常以及等待结果等步骤。理解这些步骤,能够更好地利用CompletableFuture进行复杂的异步编程。接下来,我们详细介绍了CompletableFuture提供的各种方法,包括创建对象、异步执行任务、链式操作、组合异步任务、...

  •  文暄生活科普 异步编程利器:CompletableFuture

    异步回调机制 CompletableFuture支持多种回调机制,如thenRun、thenAccept、thenApply等,用于在异步任务执行前后执行特定操作。这些回调方法允许在任务执行完成后执行后续任务或处理结果,增强了异步编程的灵活性。异常处理 当任务执行异常时,CompletableFuture会调用whenComplete回调函数进行处理。通过这种方式,可以确...

  •  翡希信息咨询 Java 异步编程的完美利器:CompletableFuture 指北

    CompletableFuture是Java异步编程中的完美利器,主要原因如下:解决了Future与FutureTask的不足:异步回调机制:CompletableFuture提供了异步回调功能,弥补了Future接口缺乏回调的不足。任务管理:可以主动完成或取消任务,相比Future提供了更灵活的任务管理手段。丰富的功能:任务创建:支持使用Runnable、Supplier接口...

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

编程相关话题

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