completablefuture 조인 대 get


91

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());
}

두 가지 방법을 모두 시도했지만 결과에는 차이가 없습니다.


9
get()확인 된 예외를 포착해야합니다. 당신이에서 변경할 때 그 차이를주의해야 get()하는 join()당신이 imediately 둘을 알리는 컴파일러 오류 얻을 것이다로서, InterruptedException도하는 것은 ExecutionException에서 발생하지 않습니다 try블록을.
Holger

5
@ holi-java : join()중단 할 수 없습니다.
Holger

@Holger 네, 선생님. 작업을 중단 할 수 없다는 것을 알았습니다.
holi-java

8
그것이 요구 하는 인터페이스를 구현 get하기 때문에 잘 존재 합니다. 퓨처를 결합 할 때 람다 식에서 확인 된 예외를 잡을 필요가 없도록하기 위해 도입되었을 가능성이 높습니다. 다른 모든 사용 사례에서는 원하는 것을 자유롭게 사용하십시오. CompletableFutureFuturejoin()
Holger

1
조인을 사용하거나 스레드에서 두 블록으로 얻는 것이 실제로 의미가 있습니까? 대신 다른 컴포지션 메서드를 사용하여 비동기 함수 체인을 생성하여이를 비동기로 만들 수는 없습니다. 그러나 예를 들어 완전한 미래를 반환하는 컨트롤러 메소드에 의해 호출되는 스프링의 서비스 메소드의 경우 get 또는 join in service 메소드를 전혀 호출하지 않는 것이 더 합리적입니다.
Shailesh Vaishampayan

답변:


105

유일한 차이점은 메서드가 예외를 throw하는 방법입니다. 인터페이스에서 다음과 같이 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()메서드는 확인 된 예외를 throw하지 않습니다 .

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()구현을 모두 찾을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.