나누고 싶은 개발 이야기

Data Engineer로서 기록하고 공유하고 싶은 기술들. 책과 함께 이야기합니다.

Language/Java

[Java8] CompletableFuture 정리

devidea 2017. 8. 9. 14:07
기존 Future 인터페이스는 비동기 계산의 결과로 제공하기 위해 Java5에서 추가되었지만, 이런 계산들을 결합하거나 오류를 처리할 방법이 없었다.

그래서 Java 8에서 CompletableFuture가 추가되었다.
CompletableFuture은 Future 뿐만 아니라 CompletionStage도 상속하는데,
CompletionStage의 특징을 살펴보면 CompletableFuture의 장점을 알 수 있다.

CompletionStage는 결국은 계산이 완료될 것이라는 의미의 약속이다.
계산의 완료는 단일 단계의 완료 뿐만 아니라 다른 여러 단계 혹은 다른 여러 단계 중의 하나로 이어질 수 있음도 포함한다.
뿐만 아니라 각 단계에서 발생한 에러를 관리하고 전달할 수 있다.

지금부터 CompletableFuture를 코드를 통해 기본적인 사용법을 알아보자.

1. 가장 간단한 비동기 계산
CompletableFuture.supplyAsync(this::sendMsg);

팩토리 메서드 supplyAsyncsupplier를 인수로 받아서 CompletableFuture를 반환한다. 비동기적으로 실행해서 결과를 생성한다.
ForkJoinPoolExecutor 중 하나가 Supplier를 실행할 것이다. (ForkJoinPool에 대해서는 다음 링크를 확인)
두번째 인수를 받는 오버로드 함수에서 다른 Executor를 선택적으로 전달할 수 있다.


2. 콜백함수 붙이기
콜백의 장점은 비동기 계산을 수행할 때 결과를 기다리지 않고 다음 작업을 정의할 수 있다는데 있다.

CompletableFuture.supplyAsync(this::sendMsg) 
                 .thenAccept(this::notify);

thenAccept는 앞선 계산의 결과의 콜백 메서드로 전달된 Consumer를 실행한다.


3. 여러 콜백함수 묶기
thenAccpet는 Consumer가 void를 반환하기 때문에 다른 콜백함수로 값을 전달할 수가 없다.
이때 thenApply를 사용하면 CompletableFuture를 반환하기 때문에 또다른 콜백함수를 연결할 수 있다.

CompletableFuture.supplyAsync(this::findReceiver)
                     .thenApply(this::sendMsg)
                     .thenAccept(this::notify);


4. 다른 비동기 코드와 조합하기
다른 CompletionStage와의 조합을 통해 새로운 CompletionStage를 만들어야 할 필요도 있다.
이때 thenCompose를 사용한다. (thenApply vs thenCompose 링크)
thenCompose가 flatmap과 비슷하다고 생각하면 좋다.

CompletableFuture.supplyAsync(this::findReceiver) 
                 .thenCompose(CompletableFuture.supplyAsync(() -> other.getReceiver()));


5. 에러 처리
CompletableFuture 작업을 진행하던 중 에러가 발생하게 되면 특정 함수를 통해 에러를 처리할 수 있다.

CompletableFuture.supplyAsync(this::failingMsg) 
                 .exceptionally(ex -> new Result(Status.FAILED))
                 .thenAccept(this::notify);


6. 여러개의 계산에 의존적인 콜백
CompletableFuture<String> to = CompletableFuture.supplyAsync(this::findReceiver);
CompletableFuture<String> text = CompletableFuture.supplyAsync(this::createContent);
to.thenCombine(text, this::sendMsg);

thenCombine은 2개의 비동기 계산을 먼저 처리한 결과로 BiFunction을 실행하도록 되어 있다.


[참고]


반응형

'Language > Java' 카테고리의 다른 글

[Java8] sorted groupBy  (0) 2019.01.11
[multi thread] java.util.concurrent Part 1  (0) 2019.01.04
Dynamic Proxies  (0) 2017.08.29
[Java8] 람다란 무엇인가?  (0) 2017.08.09
이름 재사용과 관련된 기술  (0) 2016.10.13