繁体   English   中英

completableFuture whenComplete 奇怪的行为

[英]completableFuture whenComplete strange behavior

我在使用 completableFutures 时遇到了一些奇怪的行为 请参阅下面的代码片段,以便于更好地理解。 我遍历消息列表并在每条消息上调用 handleMessage。 handleMessage 方法首先调用 getDataContentIdByService,最后调用 mappingService.process 方法。

但问题是一旦getDataContentIdByService方法处理完成,在 mappingService.process 方法执行完成之前,调用返回到 whenComplete 阶段。

我想要的是 getDataContentIdByService 和 mappingService.process 方法应按顺序完成执行,然后应调用 whenComplete 阶段。

我的代码有问题..还是? 有人可以帮忙吗?


Completablefuture.allOf(messages.getList().stream()
        .filter(this::msgOkOrLog)
        .filter(this::notOnDenyList)
        .map(msg -> handleMessage(msg, messages.getTrackingIdentifier(), messages.getMessageType()))
        .toArray(CompletableFuture<?>[]::new))
      .whenComplete((input, exception) -> countErrorsInContainer(messages));

处理消息函数


    protected CompletableFuture<Void> handleMessage(InternalProxyMessage message,
        TrackingIdentifier containerTid, MessageType messageType) {
    return getDataContentIdByService(message)
                       .thenAccept(message::setContentId)
                       .thenAccept(  
              mappingService.process(message)
                      .exceptionally(
                              ex -> {
                                  throw new InternalServerErrorException("Unmanaged Error", ex);
                                }
                              })));
    }

您的示例可以大大简化:

public static void main(String[] args) {

    CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> "initiated");
    CompletableFuture<Void> cf2 = cf1.thenAccept(x -> {
        CompletableFuture<String> response = composed(x);
        return;
    });
    System.out.println("Is it done : " + cf2.isDone());
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));

}

private static CompletableFuture<String> composed(String s) {
    return CompletableFuture.supplyAsync(() -> {
        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
        System.out.println("composed is actually finished");
        return "done";
    });
}

cf1完成后, thenAccept会被调用; 当然,因为composed被称为在不同的线程(即CompletableFuture::supplyAsync ), return声明将就会结束前命中。 运行上面的例子显示:

Is it done : true
composed is actually finished

另一方面,如果您将代码更改为:

CompletableFuture<String> cf2 = cf1.thenCompose(x -> {
     CompletableFuture<String> response = composed(x);
     return response;
});

您现在正在返回的的结果composed 所以当cf1完成时, thenCompose会被调用; 所以cf2只会在内心的未来完成时才会完成。

暂无
暂无

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

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