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());
}
我尝试了两种方法,但结果没有差异。
由于
答案 0 :(得分:47)
唯一的区别是方法如何抛出异常。 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
方法
CompletableFuture<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()
实施here