В чем разница между CompletableFuture.get()
и CompletableFuture.join()
?
Ниже мой код:
List<String> process() {
List<String> messages = Arrays.asList("Msg1", "Msg2", "Msg3", "Msg4", "Msg5", "Msg6", "Msg7", "Msg8", "Msg9",
"Msg10", "Msg11", "Msg12");
MessageService messageService = new MessageService();
ExecutorService executor = Executors.newFixedThreadPool(4);
List<String> mapResult = new ArrayList<>();
CompletableFuture<?>[] fanoutRequestList = new CompletableFuture[messages.size()];
int count = 0;
for (String msg : messages) {
CompletableFuture<?> future = CompletableFuture
.supplyAsync(() -> messageService.sendNotification(msg), executor).exceptionally(ex -> "Error")
.thenAccept(mapResult::add);
fanoutRequestList[count++] = future;
}
try {
CompletableFuture.allOf(fanoutRequestList).get();
//CompletableFuture.allOf(fanoutRequestList).join();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mapResult.stream().filter(s -> !s.equalsIgnoreCase("Error")).collect(Collectors.toList());
}
Я пробовал оба метода, но не вижу разницы в результате.
java
java-8
completable-future
Номесваран
источник
источник
get()
требует, чтобы вы перехватили проверенные исключения. Вы должны заметить разницу при переходе сget()
наjoin()
, так как вы сразу же получите ошибку компилятора, в которой говорится, что ни один из нихInterruptedException
не попадаетExecutionException
вtry
блок.join()
нельзя прерывать.get
существует, потому чтоCompletableFuture
реализуетFuture
интерфейс, который его требует.join()
скорее всего, был введен, чтобы избежать необходимости перехватывать проверенные исключения в лямбда-выражениях при объединении фьючерсов. Во всех остальных случаях используйте то, что вам больше нравится.Ответы:
единственная разница в том, как методы генерируют исключения.
get()
объявлен вFuture
интерфейсе какV get() throws InterruptedException, ExecutionException;
Оба исключения являются отмеченными исключениями, что означает, что они должны обрабатываться в вашем коде. Как вы можете видеть в своем коде, автоматический генератор кода в вашей среде IDE спрашивает, создавать ли блок try-catch от вашего имени.
try { CompletableFuture.allOf(fanoutRequestList).get() } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); }
join()
Метод не выбрасывает отмеченные исключения.public T join()
Вместо этого он выдает непроверенное исключение CompletionException. Таким образом, вам не нужен блок try-catch, и вместо этого вы можете полностью использовать
exceptionally()
метод при использованииList<String> process
функции disscusedCompletableFuture<List<String>> cf = CompletableFuture .supplyAsync(this::process) .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join}'s CompletionException .thenAccept(this::processFurther);
Вы можете найти как
get()
иjoin()
осуществление здесьисточник