CompleteFuture异步执行失败却返回成功
创始人
2025-05-31 07:09:03
0

CompleteFuture异步执行失败却返回成功

1、自定义线程池

@Configuration
public class ThreadPoolConfig {public static ThreadPoolExecutor getThreadPoolExecutor() {int availableProcessors = Runtime.getRuntime().availableProcessors();return new ThreadPoolExecutor(availableProcessors,availableProcessors,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(9999),new ThreadFactoryBuilder().setNameFormat("thread-pool-%d").build(),new ThreadPoolExecutor.CallerRunsPolicy());}}

编写三个简单的异步任务,在第三个任务执行时制造异常

public static final ThreadPoolExecutor threadPoolExecutor = ThreadPoolConfig.getThreadPoolExecutor();/*** 异步任务编排*/
@GetMapping("/asyncTaskArrange")
public ResponseData asyncTaskArrange() {try {CompletableFuture.runAsync(() -> log.info("任务1"), threadPoolExecutor).thenRunAsync(() -> log.info("任务2"), threadPoolExecutor).thenRunAsync(() -> {log.info("任务3");int i = 1 / 0;}, threadPoolExecutor).exceptionally(e -> {log.error("异常信息: " + e.getMessage(), e);throw new BusinessException(e.getMessage());});return new ResponseData<>(StatusCodeEnum.SUCCESS_CODE.getStatusCode(), "操作成功");} catch (Exception e) {log.error("程序异常信息: " + e.getMessage(), e);return new ResponseData<>(StatusCodeEnum.ERROR_CODE.getStatusCode(), "操作失败:" + e.getMessage());}
}
 

程序执行结果
在这里插入图片描述
控制台却打印了异常信息,异步任务自己捕获并抛出了异常信息,但是最外成决定程序执行成功失败的try-catch没有捕获到异常信息,所以返回成功。
在这里插入图片描述
解决办法就是让异步任务生成CompleteFuture,并调用get()方法或者join(),注意:异步任务中get()是阻塞的,使用时需要添加超时时间。

/*** 异步任务编排*/
@GetMapping("/asyncTaskArrange")
public ResponseData asyncTaskArrange() {try {CompletableFuture future = CompletableFuture.runAsync(() -> log.info("任务1"), threadPoolExecutor).thenRunAsync(() -> log.info("任务2"), threadPoolExecutor).thenRunAsync(() -> {log.info("任务3");int i = 1 / 0;}, threadPoolExecutor).exceptionally(e -> {log.error("异常信息: " + e.getMessage(), e);throw new BusinessException(e.getMessage());});// future.get(10, TimeUnit.SECONDS);future.join();return new ResponseData<>(StatusCodeEnum.SUCCESS_CODE.getStatusCode(), "操作成功");} catch (Exception e) {log.error("程序异常信息: " + e.getMessage(), e);return new ResponseData<>(StatusCodeEnum.ERROR_CODE.getStatusCode(), "操作失败:" + e.getMessage());}
}
 

再次执行程序,就能返回接口正确的执行结果
在这里插入图片描述

在这里插入图片描述

异步任务异常信息处理方法

handle

handle需要在可能发生异常的异步方法后调用,e表示上一个异步任务的异常信息,如果为null,表示执行成功,否则发现异常,需要抛出异常信息。

/*** handle处理异步异常*/@GetMapping("/asyncHandle")public ResponseData asyncHandle() {try {CompletableFuture future = CompletableFuture.runAsync(() -> log.info("任务1"), threadPoolExecutor).thenRunAsync(() -> log.info("任务2"), threadPoolExecutor).thenRunAsync(() -> {log.info("任务3");int i = 1 / 0;}, threadPoolExecutor).handle((result, e) -> {if (e != null) {log.error("异常信息: " + e.getMessage(), e);throw new BusinessException(e.getMessage());} else {return null;}});// future.get(10, TimeUnit.SECONDS);future.join();return new ResponseData<>(StatusCodeEnum.SUCCESS_CODE.getStatusCode(), "操作成功");} catch (Exception e) {log.error("程序异常信息: " + e.getMessage(), e);return new ResponseData<>(StatusCodeEnum.ERROR_CODE.getStatusCode(), "操作失败:" + e.getMessage());}}
 

在这里插入图片描述
现在改变handle的位置,放在不会方式异常的异步任务之后,再次进行测试,依然能捕获到异常,所以handle是会捕获一整个编排的异步任务链。

/*** handle处理异步异常*/@GetMapping("/asyncHandle")public ResponseData asyncHandle() {try {CompletableFuture future = CompletableFuture.runAsync(() -> log.info("任务1"), threadPoolExecutor).thenRunAsync(() -> log.info("任务2"), threadPoolExecutor).handle((result, e) -> {if (e != null) {log.error("异常信息: " + e.getMessage(), e);throw new BusinessException(e.getMessage());} else {return null;}}).thenRunAsync(() -> {log.info("任务3");int i = 1 / 0;}, threadPoolExecutor);// future.get(10, TimeUnit.SECONDS);future.join();return new ResponseData<>(StatusCodeEnum.SUCCESS_CODE.getStatusCode(), "操作成功");} catch (Exception e) {log.error("程序异常信息: " + e.getMessage(), e);return new ResponseData<>(StatusCodeEnum.ERROR_CODE.getStatusCode(), "操作失败:" + e.getMessage());}}
 

在这里插入图片描述

whenComplete

whenComplete任务执行完毕之后的回调方法,也是通过入参中的e来判断上一个异步任务是否存在异常。

/*** handle处理异步异常*/@GetMapping("/asyncWhenComplete")public ResponseData asyncWhenComplete() {try {CompletableFuture future = CompletableFuture.runAsync(() -> log.info("任务1"), threadPoolExecutor).thenRunAsync(() -> log.info("任务2"), threadPoolExecutor).thenRunAsync(() -> {log.info("任务3");int i = 1 / 0;}, threadPoolExecutor).whenComplete((result , e) -> {if (e != null) {log.error("异常信息: " + e.getMessage(), e);throw new BusinessException(e.getMessage());}});// future.get(10, TimeUnit.SECONDS);future.join();return new ResponseData<>(StatusCodeEnum.SUCCESS_CODE.getStatusCode(), "操作成功");} catch (Exception e) {log.error("程序异常信息: " + e.getMessage(), e);return new ResponseData<>(StatusCodeEnum.ERROR_CODE.getStatusCode(), "操作失败:" + e.getMessage());}}
 

exceptionally

如果编排的异步任务执行异常会执行exceptionally,如果执行正常,会返回执行正常的结果。

相关内容

热门资讯

分别的签名 与分别有关的签名 ... 人生总是在兜兜转转,有聚便会有散,在签名里,有哪些句子是与分别有关的呢?下面请欣赏太阳教育网小编为大...
个性签名骂朋友的话语 个性签名...  阁下长得真是天生励志!比较有个性一点儿的骂朋友的话语还有哪些呢?下面是太阳教育网小编为你搜集的个性...
个性签名的话 QQ个性签名的话... 得不到的,会一直被渴望着,而失去的,也总是被铭记的。适合用来做qq个性签名的话语还有哪些呢?下面是太...
最新或2023(历届)最新唯美... 喜欢唯美古风的你,知道在最新或2023(历届)出现了哪些与唯美古风有关的签名吗?下面请欣赏太阳教育网...
兄弟分别的签名 表达兄弟分别的... 兄弟是我们在这一生中难得的朋友,知己,当我们与兄弟分离的时候,如何用一句签名来表达我们当时的心情?下...
java基础:Java中vol... 一、内存模型的相关概念 大家都知道,计算机在执行程序时,每条指令都是在C...
Dubbo的独门绝技,SPI实... 文章目录前言普通SPI实现原理实例化扩展点源码分析扩展点加载流程分析LoadingStrategy分...
心灰意冷伤感说说短语 撕心裂肺...   记住我能把你宠上天也能杀你不眨眼  像被人在身后狠狠刺中了心 我心碎的声音感觉很清晰  爱是想你...
格言的话 励志经典格言 励志格... 只有创造,才是真正的享受,只有拚搏,才是充实的生活。这样的激励人心的励志格言还有哪些呢?下面是太阳教...
积极向上个性微信签名 描述男人...  1. 再长的路,一步步也能走完,再短的路,不迈开双脚也无法到达。  2. 人生伟业的建立,不在能知...
个性的话很 有个性的话 100... 只要不下流,我们就是主流!这样的比较具有个性的话语还有哪些呢?下面是太阳教育网小编为你分享的很有个性...
个性签名送给贱人的话 贱人闭嘴... 别人要开飞机去撞双子星才行,而你只要跳伞就有同样的威力。骂贱人时说的很有个性的话语还有哪些呢?下面是...
java LinkedHash... 目录 一、前言 二、LinkedHashSet简介 三、LinkedHashSet的底层实现 四、L...
QT学习(二)——按钮相关接口... 2.1 按钮相关接口 QPushButton 继承于 QAbstractButton 继承于 QWi...
让人心碎的伤感说说短语 让人心...   第一眼就心动的人,要怎么做朋友。  你要是腻了就走吧放心我不赖着你。  是时候该离开那个不属于我...
心碎到窒息的说说短语 心碎了伤...   时间让我忘了你的脸,却忘不了那些爱恋。  喂,我喜欢你“大冒险又输了?”“嗯”其实他不知道这也是...
六一儿童节看望福利院儿童活动策...  “六·一”儿童节看望福利院儿童活动策划最新或2023(历届)  六月,是孩子的节日,六月,是童年的...
幽默励志个性签名最新或2023...   01、 你要先走你必须去走的路,才能去走你想走的路。  02、 我总以为悲剧的女主角可以放肆地宣...
学校5月31日世界无烟日活动策... 1,、卫生广播:  (1)全员动员:布置学校第21个世界无烟日的宣传活动计划  (2)宣传:吸烟的危...
AtCoder Beginne... 上午第二节没课浅浅vp了一下,感觉F很有质量啊,今晚加训状压DP...