【发布时间】:2016-12-10 07:23:59
【问题描述】:
我听说CompletableFuture 能够将多个期货与runAfterBoth 合并,但如果我想合并两个以上的期货怎么办?
CompletableFuture<Boolean> a = new CompletableFuture<>();
CompletableFuture<Boolean> b = new CompletableFuture<>();
CompletableFuture<Boolean> c = new CompletableFuture<>();
List<CompletableFuture<Boolean>> list = new LinkedList<>();
list.add(a);
list.add(b);
list.add(c);
// Could be any number
for (CompletableFuture<Boolean> f : list) {
f.runAfter..
}
我的用例是我将消息发送到多个套接字以定位单个对象,该对象可能在其中任何一个上也可能不在。
我目前正在将其视为解决方案:
CompletableFuture<Boolean> a = new CompletableFuture<>();
CompletableFuture<Boolean> b = new CompletableFuture<>();
CompletableFuture<Boolean> c = new CompletableFuture<>();
List<CompletableFuture<Boolean>> list = new LinkedList<>();
list.add(a);
list.add(b);
list.add(c);
CompletableFuture<Boolean> result = new CompletableFuture<>();
Thread accept = new Thread(() -> {
for (CompletableFuture<Boolean> f : list)
if (f.join() != null)
result.complete(f.join());
});
accept.start();
// Actual boolean value returned
result.get();
但这有点乱。就我而言,我想在得到有效结果(非空)后立即继续处理,而不是等待无效结果。
例如,a 需要 5 秒,即使 b 已经在 2 秒内完成,循环也在等待它;但循环不知道这一点,因为它仍在等待a。
是否有一种模式可用于加入多个异步期货,我可以在成功完成后立即做出响应?
另一种可能性:
public static class FutureUtil {
public static <T> CompletableFuture<T> anyOfNot(
Collection<CompletableFuture<T>> collection,
T value,
T defaultValue)
{
CompletableFuture<T> result = new CompletableFuture<>();
new Thread(() -> {
for (CompletableFuture<T> f : collection) {
f.thenAccept((
T r) -> {
if ((r != null && !r.equals(value))
|| (value != null && !value.equals(r)))
result.complete(r);
});
}
try {
for (CompletableFuture<T> f : collection)
f.get();
}
catch (Exception ex) {
result.completeExceptionally(ex);
}
result.complete(defaultValue);
}).start();
return result;
}
}
使用示例:
CompletableFuture<Boolean> a = new CompletableFuture<>();
CompletableFuture<Boolean> b = new CompletableFuture<>();
CompletableFuture<Boolean> c = new CompletableFuture<>();
List<CompletableFuture<Boolean>> list = new LinkedList<>();
list.add(a);
list.add(b);
list.add(c);
CompletableFuture<Boolean> result = FutureUtil.anyOfNot(list, null, false);
result.get();
【问题讨论】:
标签: java asynchronous completable-future