请考虑以下代码:
final CompletableFuture<Object> future = giveMeFuture();
future.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
}).exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
future.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " + throwable.getLocalizedMessage());
return null;
});
我注意到以下行为:
未来正常完成时,仅打印EXCEPTION 1
。这是预期的,因为我们在thenAcceptAsync
。
如果未来异常完成,则会同时打印EXCEPTION 1
和EXCEPTION 2
。
我只想在执行EXCEPTION 1
时发生异常时打印thenAcceptAsync
。所以在第二种情况下,当异常完成未来时,我只想打印EXCEPTION 2
。
如何使用CompletableFuture
执行此操作?我知道我可以在try / catch
中添加一个好的旧thenAcceptAsync
,但我想知道是否可以仅使用CompletableFuture
功能来完成此操作。
更新
以下流程不起作用:
future
.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
return null;
})
.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
如果我们输入EXCEPTION 2
流程,我们会返回null
。现在使用thenAcceptAsync
参数调用null
。我们可以对参数null
添加o
检查,但我认为这不是一个好主意。我们正在唤醒执行程序线程,发现参数o
是null
:
.thenAcceptAsync(o -> {
if (o != null) {
// do something with the parameter
throw new RuntimeException("Some random exception happened.");
}
})
答案 0 :(得分:1)
怎么样:
future
.handleAsync((object, throwable) -> {
if (throwable !=null) {
System.out.println("EXCEPTION from future completion: " + throwable.getClass().getName());
return null;
}
else {
throw new IllegalStateException("async processing failed");
}
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION from completion stage: " + throwable.getClass().getName());
return null;
});
或将您的代码更改为:
future
.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
return null;
})
.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
每次将操作链接到将来时,它都会与其他“链接”分开执行。你正在制作两个操作链,一个是future.thenAcceptAsync
,另一个是future.exceptionally
,它们彼此分开执行。