Java CompletableFuture anyOf N

时间:2019-02-22 19:35:58

标签: java completable-future

我正在寻找用Java给出的方式,让我们说一个成功完成或失败的第一个N的Async CompletableFutures列表。除非没有N个成功,否则任何失败都将被忽略。

有什么例子吗?

谢谢

1 个答案:

答案 0 :(得分:0)

也许是这样吗?

public static <T> CompletableFuture<List<T>> firstSuccessful(
        List<CompletableFuture<T>> list, int n) {

    int maxFail = list.size() - n;
    if(maxFail < 0) throw new IllegalArgumentException();

    AtomicInteger fails = new AtomicInteger(0);
    List<T> rList = new ArrayList<>(n);

    CompletableFuture<List<T>> result = new CompletableFuture<>();

    BiConsumer<T,Throwable> c = (value,failure) -> {
        if(failure != null) {
            if(fails.incrementAndGet() > maxFail) result.completeExceptionally(failure);
        }
        else {
            if(!result.isDone()) {
                boolean commit;
                synchronized(rList) {
                    commit = rList.size() < n && rList.add(value) && rList.size() == n;
                }
                if(commit) result.complete(Collections.unmodifiableList(rList));
            }
        }
    };
    for(CompletableFuture<T> f: list) f.whenComplete(c);
    return result;
}

尽管顺序不确定,但它以List的形式返回N个结果。只是返回Set会改变语义,即当多个期货的评估结果相等时。

如果有足够的成功完成,列表将始终具有长度N。它也将在第N个结果可用时完成,而无需等待其他期货。一旦有太多失败的期货,以致无法再成功完成N个值,则所产生的期货将异常地完成。实际上,这将是失败期货中的任意抛弃。