What is the difference between the get()
and join()
methods of the CompletableFuture<T>
class?
Below is the my code:
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());
}
I have tried with both methods but I see no difference in result.
get()
requires you to catch checked exceptions. You should notice the difference when you change fromget()
tojoin()
, as you will imediately get a compiler error saying that neitherInterruptedException
norExecutionException
are thrown in thetry
block. – Aspirationjoin()
can not get interrupted. – Aspirationget
exists, becauseCompletableFuture
implements theFuture
interface which mandates it.join()
most likely has been introduced, to avoid needing to catch checked exceptions in lambda expressions when combining futures. In all other use cases, feel free to use whatever you prefer. – Aspiration