Ожидание allOf в Java
Иногда нужно знать, что все фоновые шаги
закончились, неважно успех это или сбой.
Статический метод allOf принимает
несколько CompletableFuture<?> и
возвращает CompletableFuture<Void>,
который завершится, когда завершится каждый
из аргументов.
Сами результаты allOf не собирает: после
join у обёртки нужно прочитать каждый
исходный объект через join или
getNow:
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture<String> a =
CompletableFuture.supplyAsync(() -> "A");
CompletableFuture<String> b =
CompletableFuture.supplyAsync(() -> "B");
CompletableFuture.allOf(a, b).join();
String line = a.join() + b.join();
System.out.println(line);
}
}
Если хотя бы один участник завершился с ошибкой,
allOf тоже завершится исключением при
join. Остальные задачи при этом могут
ещё выполняться: отмену нужно планировать
отдельно.
Метод anyOf ждёт первого завершившегося
участника и возвращает CompletableFuture<Object>
с его результатом. Удобно для дублирующих
запросов к зеркалам, когда достаточно самого
быстрого ответа:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
CompletableFuture<String> slow =
CompletableFuture.supplyAsync(() -> {
sleep(300);
return "slow";
});
CompletableFuture<String> fast =
CompletableFuture.supplyAsync(() -> {
sleep(50);
return "fast";
});
Object winner = CompletableFuture
.anyOf(slow, fast)
.join();
System.out.println(winner);
}
static void sleep(long ms) {
try {
TimeUnit.MILLISECONDS.sleep(ms);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
Три асинхронные задачи возвращают 1,
2 и 3. Дождитесь завершения
всех задач и выведите сумму результатов.