Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9 CompletableFuture의 delayedExecutor() 메서드, 언제 어떻게 사용할까?

Java 9에서는 CompletableFuture 클래스에 delayedExecutor() 메서드가 새롭게 추가되었습니다. 이 메서드는 지정한 지연 시간(delay)이 지난 후에 작업을 실행할 수 있는 Executor 객체를 반환하며, 비동기 작업의 실행 시점을 의도적으로 늦춰야 할 때 매우 유용합니다.

CompletableFuture는 두 가지 오버로드(overload)된 delayedExecutor() 메서드를 제공합니다.

  • 첫 번째 형태: CompletableFuture가 내부적으로 사용하는 기본(default) Executor 객체를 통해 지연 시간이 지난 뒤 작업을 실행하는 Executor를 반환합니다.
  • 두 번째 형태: 개발자가 직접 인자로 전달한 Executor 객체를 사용하여 지연 시간이 지난 뒤 작업을 실행하는 Executor를 반환합니다.

문법(Syntax)

public static Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
public static Executor delayedExecutor(long delay, TimeUnit unit)
  • delay: 작업 실행 전 대기할 시간
  • unit: 지연 시간의 단위 (초, 밀리초 등)
  • executor: 지연 후 실제 작업을 수행할 Executor 객체 (생략 가능)

예제 코드

아래 예제는 completeAsync()와 함께 delayedExecutor()를 사용하여 3초 후에 비동기 작업이 실행되도록 구성한 코드입니다.

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class DelayedExecutorMethodTest {
   public static void main(String args[]) throws InterruptedException, ExecutionException {
      CompletableFuture<String> future = new CompletableFuture<>();
      future.completeAsync(() -> {
         try {
            System.out.println("inside future: processing data...");
            return "tutorialspoint.com";
         } catch(Throwable e) {
            return "not detected";
         }
      }, CompletableFuture.delayedExecutor(3, TimeUnit.SECONDS))
                          .thenAccept(result -> System.out.println("accept: " + result));
      for(int i = 1; i <= 5; i++) {
         try {
            Thread.sleep(1000);
         } catch(InterruptedException e) {
            e.printStackTrace();
         }
         System.out.println("running outside... " + i + " s");
      }
   }
}

실행 결과

running outside... 1 s
running outside... 2 s
inside future: processing data...
accept: tutorialspoint.com
running outside... 3 s
running outside... 4 s
running outside... 5 s

실행 결과를 보면 메인 스레드는 계속해서 "running outside..."를 출력하고 있지만, 비동기 작업은 정확히 3초가 지난 후에 실행되어 "inside future: processing data..."와 "accept: tutorialspoint.com"이 출력되는 것을 확인할 수 있습니다.

언제 delayedExecutor()를 사용해야 할까?

  • 작업 시작 지연이 필요한 경우: 서버 부하 분산을 위해 요청 처리를 잠시 미루거나, 초기화가 완료될 때까지 작업 실행을 늦추고 싶을 때 유용합니다.
  • 타임아웃·재시도 로직 구현: 일정 시간 후에 재시도(retry) 작업을 실행하거나, 지연 기반 폴링(polling) 로직을 간결하게 작성할 수 있습니다.
  • ScheduledExecutorService의 간편한 대체: 별도의 스케줄러 설정 없이 CompletableFuture의 비동기 체인 안에서 지연 실행을 손쉽게 처리할 수 있습니다.

이처럼 delayedExecutor()는 비동기 작업에 지연을 도입해야 하는 다양한 상황에서 코드를 단순하고 읽기 쉽게 만들어 주는 강력한 도구입니다.