Future 는 비동기 작업 수행의 결과를 담고있는 자바의 인터페이스이다.
ListenableFuture 는 Spring 에서 제공하는 인터페이스로 Future에 콜백을 등록해 사용할 수 있도록 한 방식이다.
자바 8 때 소개된 CompletableFuture 는 여러 비동기 작업을 결합하고 처리하는데 기존 방식에 비해 훨씬 편하게 수행할 수 있다.
아래는 간단히 반환값이 없는 2개 비동기 작업을 수행하는 예시이다.
CompletableFuture .runAsync(() -> log.info("runAsync")) .thenRun(() -> log.info("thenRun"));
반환값이 있는 비동기 작업은 아래와 같이 할 수 있다.
CompletableFuture .supplyAsync(() -> 1) // 비동기적으로 값을 제공 (외부 API 호출 등) .thenApply(i -> i + "hi") // 값을 가공 .exceptionally(e -> e.getMessage()) // 작업 중 오류가 발생했을 경우 사용될 값 .thenAccept(i -> System.out.println(i)); // 값을 사용
CompletableFuture 에서 할 수 있는 작업들은 CompletionStage 에 정의되어있다.
CompletableFuture 에서 수행되는 작업은 내부에 관리되는 ForkJoinPool에 의해 실행된다.
이때 ForkJoinPool의 병렬도가 1 이상이면 ForkJoinPool, 아니면 각 작업마다 하나의 스레드가 할당되는 ThreadPerTaskExecutor가 사용된다.
(풀 병렬도는 ForkJoinPool.getCommonPoolParallelism() 메소드로 가져오는데,, 이게 정확히 무슨 값을 의미하는지는 잘 모르겠음. 아시는 분 댓글 남겨주시길 바랍니다)
메소드 네이밍에 따라 *Async 로 호출되는 메소드는 두 번째 인자로 특정 스레드풀에서 실행되게 할 수도 있다.
만약 어떤 작업 내에서 리턴값이 CompletableFuture가 되어야하는 경우 thenCompose 를 사용한다.
이는 또다른 비동기 작업을 수행하되, CompletableFuture 타입이 아닌경우 CompletableFuture로 변환하여 리턴할 수 있다.
아래 예시는 스프링의 ListenableFuture를 중간작업으로 수행하는데 CompletableFuture 체인에 연결한 예시이다.
// Callback 방식의 ListenableFuture를 CompletableFuture로 변환해주는 메소드 // ListenableFuture 콜백에 CompletableFuture 방식의 메소드를 전달한다. public static <T> toCompletableFuture(ListenableFuture<T> lf) { CompletableFuture<T> cf = new CompletableFuture<>(); lf.addCallback(cf::complete, cf::completeExceptionally); return cf; }
CompletableFuture .supplyAsync(() -> 1) .thenCompose(i -> { ListenableFuture<Integer> lf = doListenableFutureJob(); return toCompletableFuture(lf); // CompletableFuture 체인에 연결해주기위해 바꿔줌 }) .thenAccept(i -> System.out.println(i));
'Back-End > Reactive Programming' 카테고리의 다른 글
Java / Servlet 비동기 기술 흐름 with Spring (0) | 2022.01.13 |
---|---|
리액티브 프로그래밍 시리즈 3 - 스레드 스케쥴링 (Thread scheduling) (0) | 2021.08.25 |
리액티브 프로그래밍 시리즈 2 - Operators와 Reactor 맛보기 (0) | 2021.08.21 |
리액티브 프로그래밍 시리즈 1 - Reactive Streams 개요 (0) | 2021.08.17 |