Completable Future 가이드 (파트1)

Chanhyeong LEE
3 min readNov 26, 2017

--

http://www.baeldung.com/java-completablefuture 을 보고 번역했습니다.

Java8 Concurrency API improvement 로 들어간 CompletableFuture를 이야기하고자 한다.

비동기 Java

우리는 어떤 작업을 일련의 과정으로 이해한다. 그런데 비동기 연산은 Callback 으로 다음 스텝을 표현한다. 이는 더 코드를 읽기 힘들게 하며 각 스텝마트 에러 처리를 할 때면 더 난감해진다.

Callback Hell

Java5 에 Future 인터페이스가 들어가 있긴했는데 비동기 연산들을 합치거나 에러를 핸들링 할 수는 없었다. 결국 Java8에 CompletableFuture 클래스가 들어왔고 Future 인터페이스에 이어 여러 비동기 작업을 조합할 수 있는 메소드를 정의한 CompletionStage 인터페이스가 들어왔다. 이 ComputableFuture 에는 비동기 작업을 조합하고 에러를 핸들링 할 수 있는 50개의 메소드가 있다.

간단한 Future 로 CompletableFuture 사용하기

CompletableFutureFuture 인터페이스로 구현했기 때문에 당연히 Future 의 구현체로 사용가능하다. 간단하게 사용하는 방법은 이러하다. CompletableFuture 을 인자가 없는 생성자로 만든다. 그 뒤 이 참조를 Consumer 에게 넘긴다. (여기서 말하는 Consumer 는 단순히 Future 를 참조를 가지며 Future 로 부터 넘어오는 값을 받는 쪽을 말한다.) 그리고 Futurecomplete 메소드를 호출하며 Consumer 쪽으로 값을 전달할 수 있다. Consumerget 메소드를 호출하여 이 값을 전달 받는다. 이 때 get 메소드가 호출되면 값을 받을 때까지 호출한 Thread 는 Blocking 이 된다.

실제 코드를 보면 이렇게 짤 수 있다.

여기 caculateAsync 메소드를 호출하면 바로 Future 구현체를 반환 받는다. 내부적으로는 다른 Thread 에서 0.5초 sleep 후 complete 를 호출하여 Consumer 쪽으로 “Hello” 를 전달한다. 그럼 Consumer 쪽에선 get 메소드를 호출하면 이 값을 받을 수 있다.

get 메소드를 호출 할 때 어떤 예외가 있었는지 확인하고 있으면 Throw 를 한다. 이 때 발생할 수 있는 예외는 두 가지가 있다. ExecutionException (Future 실행 중 예외 발생), InterruptedException (실행 중인 Thread 에서 interrupt 가 발생한 경우)

만약 Consumer 로 보낼 값을 바로 알고 있다면 Future 생성 동시에 바로 값을 넣어줄 수 있다. 이 때 get 메소드에서는 Blocking 되는 일 없이 바로 값을 가져온다.

Future 실행을 cancel 하는 경우도 있다. 이는 Futurecancel 메소드를 호출한 경우인데 이 상황에서 comsumer 쪽에서 get 메소드를 호출하면 CancellationException 을 Throw 한다. 참고로 cancel 메소드는 mayInterruptIfRunning 라는 Boolean 인자를 받는데 CompetableFuture 에서는 Ture 이든 False 이든 아무 영향이 없다.

--

--