Apa perbedaan antara CompletableFuture.get()
dan CompletableFuture.join()
?
Di bawah ini adalah kode saya:
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());
}
Saya telah mencoba dengan kedua metode tersebut tetapi saya tidak melihat perbedaan hasilnya.
java
java-8
completable-future
Nomeswaran
sumber
sumber
get()
mengharuskan Anda untuk menangkap pengecualian yang dicentang. Anda harus melihat perbedaan ketika Anda mengubah dariget()
kejoin()
, karena Anda Mulailah segera akan mendapatkan kesalahan kompilator mengatakan bahwa baikInterruptedException
atauExecutionException
dibuang ditry
blok.join()
tidak dapat disela.get
ada, karenaCompletableFuture
alat iniFuture
antarmuka yang mengamanatkan itu.join()
kemungkinan besar telah diperkenalkan, untuk menghindari keharusan untuk menangkap pengecualian yang dicentang dalam ekspresi lambda saat menggabungkan masa depan. Dalam semua kasus penggunaan lainnya, silakan gunakan apa pun yang Anda suka.Jawaban:
satu-satunya perbedaan adalah bagaimana metode membuang pengecualian.
get()
dideklarasikan dalamFuture
antarmuka sebagaiV get() throws InterruptedException, ExecutionException;
Pengecualian keduanya adalah pengecualian yang dicentang yang berarti mereka perlu ditangani dalam kode Anda. Seperti yang Anda lihat di kode Anda, generator kode otomatis di IDE Anda bertanya apakah akan membuat blok coba-tangkap atas nama Anda.
try { CompletableFuture.allOf(fanoutRequestList).get() } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); }
The
join()
metode tidak membuang diperiksa pengecualian.public T join()
Sebagai gantinya, ia melempar CompletionException yang tidak dicentang . Jadi Anda tidak memerlukan blok coba-tangkap dan sebaliknya Anda dapat memanfaatkan sepenuhnya
exceptionally()
metode saat menggunakanList<String> process
fungsi disscusedCompletableFuture<List<String>> cf = CompletableFuture .supplyAsync(this::process) .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join}'s CompletionException .thenAccept(this::processFurther);
Anda dapat menemukan keduanya
get()
danjoin()
implementasinya di sinisumber