简体   繁体   English

Completablefuture 不会因异常而完成

[英]Completablefuture doesnot complete on exception

I'm kinda new to using CompletableFuture API and I have a question regarding usage of allOf .我对使用 CompletableFuture API 有点allOf ,我对allOf使用有allOf From what I read, completable-future should be in complete state and allOf logic should be executed when all associated futures complete, including completed-exceptionally .从我读到的内容来看, completable-future 应该处于完整状态,并且allOf逻辑应该在所有关联的期货完成时执行,包括completed-exceptionally But here's my smaple code for which allOf block never gets executed -但这是我的allOf块永远不会被执行的allOf代码 -

public static void test() {
    CompletableFuture<String> r1 = CompletableFuture.supplyAsync(() -> {
        try{
            Thread.sleep(1000);
            throw new RuntimeException("blahh !!!");
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    });

    CompletableFuture<String> r2 = CompletableFuture.supplyAsync(() -> "55");
    CompletableFuture<String> r3 = CompletableFuture.supplyAsync(() -> "56");
    CompletableFuture.allOf(r1, r2, r3).thenRun(() -> { System.out.println(Thread.currentThread()+" --- End."); });
    Stream.of(r1, r2, r3).forEach(System.out::println);


    try{
        System.out.println(Thread.currentThread()+" --- SLEEPING !!!");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread()+" --- DONE !!!");
    } catch (Exception e) {
        //e.printStackTrace();
    }
    Stream.of(r1, r2, r3).forEach(System.out::println);
}

The problem is not that your allOf CompletableFuture never completes.问题不在于您的allOf CompletableFuture永远不会完成。 It does.确实如此。

What causes your code not to run is thenRun 's expectation:导致您的代码无法运行的原因是thenRun的期望:

Returns a new CompletionStage that, when this stage completes normally , executes the given action.返回一个新的 CompletionStage,当这个阶段正常完成时,执行给定的操作。 See the CompletionStage documentation for rules covering exceptional completion.有关涵盖异常完成的规则​​,请参阅 CompletionStage 文档。

You probably already know that when one of allOf 's futures completes exceptionally, the resulting future also completes exceptionally:您可能已经知道,当allOf的期货之一异常完成时,产生的期货也会异常完成:

Returns a new CompletableFuture that is completed when all of the given CompletableFutures complete.返回一个新的 CompletableFuture,它在所有给定的 CompletableFuture 完成时完成。 If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture also does so, with a CompletionException holding this exception as its cause.如果任何给定的 CompletableFuture 异常完成,则返回的 CompletableFuture 也会这样做,CompletionException 将此异常作为其原因。

In short, don't use thenRun if you want to run an action on your allOf future irrespective of how it comples.简而言之,如果你想在你的allOf未来上运行一个动作,不管它如何完成,不要使用thenRun As an alternative, you can use whenComplete :作为替代方案,您可以使用whenComplete

CompletableFuture.allOf(r1, r2, r3)
        .whenComplete((a, ex) -> System.out.println(Thread.currentThread() + " --- End."));

You can also use a combination of thenRun + exceptionally , one of which will run:您还可以使用thenRun + exceptionally的组合,其中之一将运行:

CompletableFuture<Void> all = CompletableFuture.allOf(r1, r2, r3);
all.thenRun(() -> {
    System.out.println(Thread.currentThread() + " --- End.");
});
all.exceptionally(ex -> {
    System.out.println(ex);
    return null;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM