복붙노트

[SPRING] CompletableFuture allof (..). join () vs CompletableFuture.join ()

SPRING

CompletableFuture allof (..). join () vs CompletableFuture.join ()

현재 공통 스레드 풀에 일부 작업을 제출하기 위해 CompletableFuture supplyAsync () 메서드를 사용하고 있습니다. 코드 스 니펫은 다음과 같습니다.

final List<CompletableFuture<List<Test>>> completableFutures = resolvers.stream()
        .map(resolver -> supplyAsync(() -> task.doWork()))
        .collect(toList());

CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()])).join();

final List<Test> tests = new ArrayList<>();
completableFutures.stream()
        .map(completableFuture -> completableFuture.getNow())
        .forEach(tests::addAll);

위 코드와 어떻게 다른지 알고 싶습니다. 아래 코드에서 completableFuture 부모를 제거하고 getNow () 대신 completableFuture 각각에 join ()을 추가했습니다.

final List<CompletableFuture<List<Test>>> completableFutures = resolvers.stream()
        .map(resolver -> supplyAsync(() -> task.doWork()))
        .collect(toList());

final List<Test> tests = new ArrayList<>();
completableFutures.stream()
        .map(completableFuture -> completableFuture.join())
        .forEach(tests::addAll);

나는 봄 서비스에서 이것을 사용하고 스레드 풀 고갈에 문제가있다. 모든 조언을 깊이 감사드립니다.

해결법

  1. ==============================

    1.무엇보다도, .getNow ()는 작동하지 않습니다. 왜냐하면이 메소드는 미래가 아직 완료되지 않은 경우 인수로 대체 값을 요구하기 때문입니다. 미래를 여기에서 완료한다고 가정하기 때문에 join ()도 사용해야합니다.

    무엇보다도, .getNow ()는 작동하지 않습니다. 왜냐하면이 메소드는 미래가 아직 완료되지 않은 경우 인수로 대체 값을 요구하기 때문입니다. 미래를 여기에서 완료한다고 가정하기 때문에 join ()도 사용해야합니다.

    두 경우 모두 스레드 고갈에 대한 차이점이 없습니다. 진행하기 전에 모든 작업 완료를 기다리고 잠재적으로 현재 스레드를 차단합니다.

    이를 피할 수있는 유일한 방법은 결과를 동 기적으로 기대하지 않도록 코드를 리팩터링하는 것이지만, 모든 작업이 완료되면 후속 처리 작업을 수행하도록 예약하는 것입니다. 그런 다음 allOf를 사용하면 관련성이 높아집니다.

    final List<CompletableFuture<List<Test>>> completableFutures = resolvers.stream()
        .map(resolver -> supplyAsync(() -> task.doWork()))
        .collect(toList());
    
    CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture<?>[0]))
        .thenAccept(justVoid -> {
            // here, all jobs have been completed
            final List<Test> tests = completableFutures.stream()
                .flatMap(completableFuture -> completableFuture.join().stream())
                .collect(toList());
            // process the result here
        });
    

    그건 그렇고, 컬렉션에 대한 toArray 메서드에 관해서는, 나는 고대인의 지혜의 배열을 읽는 것이 좋습니다 ...

  2. from https://stackoverflow.com/questions/52370888/completablefuture-allof-join-vs-completablefuture-join by cc-by-sa and MIT license