Метод anyOf
Метод anyOf класса CompletableFuture принимает
массив или переменное число объектов CompletableFuture
и возвращает новый объект CompletableFuture, который
завершается, как только завершится любой из переданных
фьючерсов. В первый параметр мы передаем набор фьючерсов,
завершения которых нужно дождаться. Результатом нового
фьючерса всегда является объект типа Object -
значение того фьючерса, который завершился первым.
Если первым завершился фьючерс с ошибкой, то и результирующий
фьючерс завершится с этой же ошибкой.
Метод особенно полезен, когда нужно получить результат от самого быстрого из нескольких источников данных, например, при запросе к нескольким серверам и выборе самого быстрого ответа.
Синтаксис
CompletableFuture.anyOf(CompletableFuture... cfs)
Пример
Давайте создадим три асинхронных задачи с разной задержкой и дождемся завершения самой быстрой из них:
import java.util.concurrent.CompletableFuture;
public class Main
{
public static void main(String[] args)
{
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(300); } catch (InterruptedException e) {}
return "abcde";
});
CompletableFuture<String> second = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(100); } catch (InterruptedException e) {}
return "12345";
});
CompletableFuture<String> third = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(200); } catch (InterruptedException e) {}
return "hello";
});
CompletableFuture<Object> anyOfFuture =
CompletableFuture.anyOf(first, second, third);
Object res = anyOfFuture.join();
System.out.println(res);
}
}
Результат выполнения кода:
"12345"
Пример
Давайте передадим массив фьючерсов и обработаем результат
через thenAccept:
import java.util.concurrent.CompletableFuture;
public class Main
{
public static void main(String[] args)
{
CompletableFuture<Integer> first = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) {}
return 1;
});
CompletableFuture<Integer> second = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(50); } catch (InterruptedException e) {}
return 2;
});
CompletableFuture<Integer> third = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(300); } catch (InterruptedException e) {}
return 3;
});
CompletableFuture<Object> anyOfFuture =
CompletableFuture.anyOf(first, second, third);
anyOfFuture.thenAccept(res -> System.out.println(res));
anyOfFuture.join();
}
}
Результат выполнения кода:
2
Пример
Давайте посмотрим, как поведет себя метод, если самый быстрый фьючерс завершился с ошибкой:
import java.util.concurrent.CompletableFuture;
public class Main
{
public static void main(String[] args)
{
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) {}
return "abcde";
});
CompletableFuture<String> second = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("error");
});
CompletableFuture<Object> anyOfFuture =
CompletableFuture.anyOf(first, second);
try
{
anyOfFuture.join();
}
catch (Exception e)
{
System.out.println(e.getCause().getMessage());
}
}
}
Результат выполнения кода:
"error"
Смотрите также
-
метод
allOf,
который ждет завершения всех фьючерсов -
метод
supplyAsync,
который создает асинхронную задачу с результатом -
метод
thenAccept,
который обрабатывает результат фьючерса -
метод
join,
который ожидает завершения фьючерса