Полноценное объединение

В чем разница между 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());
}

Я попытался использовать оба метода, но не имел никакого различия в результате.

Спасибо

Ответ 1

Единственное отличие заключается в том, как методы генерируют исключения. get() объявлен в интерфейсе Future как

V get() throws InterruptedException, ExecutionException;

Исключения составляют оба проверенных исключения, что означает, что они должны обрабатываться в вашем коде. Как вы можете видеть в своем коде, автоматический генератор кода в вашей среде IDE спросил, есть ли блок try try для вашего имени.

try {
  CompletableFuture.allOf(fanoutRequestList).get() 
} catch (InterruptedException | ExecutionException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

Метод join() не выдает проверенные исключения.

public T join()

Вместо этого он отменяет исключение CompletionException. Таким образом, вам не нужен блок try-catch, и вы можете полностью использовать метод exceptionally() при использовании функции disccused List<String> process

CompletableFuture<List<String>> cf = CompletableFuture
    .supplyAsync(this::process)
    .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join} CompletionException
    .thenAccept(this::processFurther);

Вы можете найти как get(), так и join() реализацию здесь