Я читал, что 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();
anyOf
? - person Marco13   schedule 10.12.2016anyOf
завершится, если логическое значение вернет null. Мне нужно только будущее, которое возвращает ненулевой результат. - person Zhro   schedule 10.12.2016anyOf
, который завершится с нулевым значением. - person Zhro   schedule 10.12.2016