completablefuture join vs get


93

違いは何である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());
}

両方の方法で試しましたが、結果に違いは見られません。


10
get()チェックされた例外をキャッチする必要があります。からget()に変更するとjoin()、ブロックにどちらInterruptedExceptionExecutionExceptionスローされないというコンパイラエラーがすぐに発生するため、違いに気付くはずですtry
ホルガー2017

5
@ holi-java:join()中断できません。
ホルガー2017

@ホルガーはい、サー。タスクを中断できないことがわかりました。
holi-java 2017

9
それを義務付けるインターフェースを実装しているgetので、よく存在CompletableFutureFutureます。join()先物を組み合わせるときにラムダ式でチェックされた例外をキャッチする必要を回避するために、おそらく導入されました。他のすべてのユースケースでは、お好きなものを自由に使用してください。
ホルガー2017

1
スレッドの両方のブロックとしてjoinまたはgetを使用することは本当に意味がありますか?代わりに、他の合成方法を使用して非同期関数のチェーンを作成することにより、これを非同期にすることはできません。それは機能に依存します。しかし、たとえば、完全な未来を返すコントローラーメソッドによって呼び出された春のサービスメソッドの場合、getまたはjoin inserviceメソッドをまったく呼び出さない方が理にかなっています。
Shailesh Vaishampayan 2017

回答:


108

唯一の違いは、メソッドが例外をスローする方法です。インターフェイスで次のように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()、disscusedList<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()実装を見つけることができます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.