线程(十二)---CompletableFuture(三)

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!   

示例五:异常处理

接着上一篇记录一下CompletableFuture的异常处理,异常处理通常使用exceptionally、whenComplete、handle相关方法,他们之间有一点区别,exceptionally相当于try/catch,whenComplete和handle相当于try/finally。

以下先演示下exceptionally的使用方式,exceptionally 就相当于 catch,出现异常,将会跳过 thenApply 的后续操作,直接捕获异常,进行一场处理,代码如下:

static void exceptionally() throws Exception{
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> "执行:" + 10/0)
                .thenApply(s -> {
                    System.out.println("执行了");
                    s += "a";
                    return s;
                })
                //.exceptionally(e -> "100")
                .exceptionally(e -> {
                    System.out.println(e.getMessage());
                    return "100";
                });
        System.out.println(futureA.get());
}

执行结果如下:

可以看出如果出现异常会直接跳到exceptionally中处理异常,可以获取到异常信息并进行一些补偿操作,前面的操作直接跳过不再执行。

接下来看下whenComplete()对异常的处理,代码如下:

static void whenComplete() throws Exception{

        CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> 10/0)
                .thenApply(s -> {
                    System.out.println("执行了");
                    return s + 1;
                })
                .whenComplete((r,e) -> {
                    if(r != null && e == null){
                        System.out.println("正常执行");
                    }
                    if(e != null){
                        System.out.println("执行异常:" + e.getMessage());
                    }
                });
        System.out.println(futureA.get());
}

执行结果如下:

可以看出,出现异常后,也没执行thenApply中的操作,而是直接跳到whenComplete方法中,但是控制台还报错了,上面说到,whenComplete相当于try/finally操作,没有catch异常肯定会报错,实际用的时候需要结合exceptionally使用,如下追加exceptionally处理:

CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> 10/0)
                .thenApply(s -> {
                    System.out.println("执行了");
                    return s + 1;
                }).exceptionally(e -> {
                    System.out.println(e.getMessage());
                    return 100;
                })
                .whenCompleteAsync((r,e) -> {
                    if(r != null && e == null){
                        System.out.println("正常执行");
                    }
                    if(e != null){
                        System.out.println("执行异常:" + e.getMessage());
                    }
                });
        System.out.println(futureA.get());

执行结果如下:

handle跟whenComplete的区别是handle是有返回值的,使用handle的代码如下:

CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> 10/0)
                .thenApply(s -> {
                    System.out.println("执行了");
                    return s + 1;
                }).exceptionally(e -> {
                    System.out.println(e.getMessage());
                    return 100;
                })
                .handle((r,e) -> {
                    if(r != null && e == null){
                        System.out.println("正常执行");
                    }
                    if(e != null){
                        System.out.println("执行异常:" + e.getMessage());
                    }
                    return 1;
                });
        System.out.println(futureA.get());

执行结果如下:

从结果上看,使用handle与使用whenComplete时,除了handle需要返回结果的不同外,最后打印的结果是也不同,使用handle最终futureA打印的结果是1,也就是说使用的是handle中返回的结果,从try/catch/finally运行的流程来说这种结果也是意料之中。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值