我一直在使用CompletableFuture.allOf(...)
助手创建聚合期货,只有当它们的复合期货被标记为完成时才会“完成”,即:
CompletableFuture<?> future1 = new CompletableFuture<>();
CompletableFuture<?> future2 = new CompletableFuture<>();
CompletableFuture<?> future3 = new CompletableFuture<>();
CompletableFuture<?> future = CompletableFuture.allOf(future1, future2, future3);
我想对此功能稍作改动,在以下情况下,总体未来是完整的市场:
- 所有期货均已成功完成或
- 任何一个未来都未成功完成
在后一种情况下,聚合未来应该立即(例外地)完成,而不必等待其他未来完成,即快速失败。
为了说明这一点,请对比CompletableFuture.allOf(...)
考虑:
// First future completed, gotta wait for the rest of them...
future1.complete(null);
System.out.println("Future1 Complete, aggregate status: " + future.isDone());
// Second feature was erroneous! I'd like the aggregate to now be completed with failure
future2.completeExceptionally(new Exception());
System.out.println("Future2 Complete, aggregate status: " + future.isDone());
// Finally complete the third future, that will mark the aggregate as done
future3.complete(null);
System.out.println("Future3 Complete, aggregate status: " + future.isDone());
使用allOf(...)
,此代码产生:
Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: false
Future3 Complete, aggregate status: true
而我的替代聚合实现将在 Feature2 完成后返回“true”,因为它是一个例外。
我在 Java 标准库中找不到任何可以帮助我实现这一目标的实用程序,这感觉很奇怪……因为它是一个相对普通的用例。
从实现来看CompletableFuture.allOf(...)
,很明显这些场景背后的逻辑相当复杂。我不愿意自己写这个,我想知道是否有其他选择?