CompletableFuture<T> 类: join() vs get()

2022-08-31 07:26:12

类的 和 方法有什么区别?get()join()CompletableFuture<T>

以下是我的代码:

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-catch 块。

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

该方法不会引发选中的异常。join()

public T join()

相反,它会抛出未选中的 .因此,您不需要 try-catch 块,相反,您可以在使用 disscused 函数时完全利用方法CompletionExceptionexceptionally()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()


答案 2

除了 Dawid 提供的答案之外,get 方法还有两种类型:

get()
get(Long timeout, TimeUnit timeUnit) 

第二个 get 将等待时间作为参数,最多等待提供的等待时间。

try {
    System.out.println(cf.get(1000, TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
    ex.printStackTrace();
}

有关详细信息,请参阅本文档

  1. join() 在 CompletableFuture 中定义,而 get() 来自接口 Future
  2. join() 抛出未选中的异常,而 get() 抛出选中的异常
  3. 你可以中断 get(),然后抛出一个 InterruptedException
  4. get() 方法允许指定最长等待时间

推荐