请考虑以下代码:
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.");
}
})
怎么样:
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
,这些操作链彼此分开执行。