비동기로 실행하고 싶은데 간격을 두고 실행하고 싶을 때

생성일
Feb 4, 2025 05:30 AM
상위 항목
최종 편집 일시
Last updated February 4, 2025
태그
JAVA
하위 항목

🔍 CompletableFuture.delayedExecutor란?

CompletableFuture.delayedExecutor(long delay, TimeUnit unit)비동기 실행을 특정 시간 뒤에 시작하도록 예약하는 기능입니다.
📌 즉, runAsync() 또는 supplyAsync()가 바로 실행되지 않고, 지정한 delay 만큼 기다린 후 실행됩니다.
💡 실제 동작은 내부적으로 ScheduledThreadPoolExecutor를 사용하여 일정 시간 후에 실행하는 방식입니다.

🚀 delayedExecutor()의 기본 동작

Executor delayedExecutor = CompletableFuture.delayedExecutor(3, TimeUnit.SECONDS); CompletableFuture.runAsync(() -> System.out.println("3초 후 실행!"), delayedExecutor);
📌 설명:
  • CompletableFuture.delayedExecutor(3, TimeUnit.SECONDS)3초 후에 실행할 Executor를 생성.
  • runAsync() 실행 시, 즉시 실행되지 않고 3초 후에 실행됨.
결과:
(3초 대기) 3초 후 실행!

🎯 CompletableFuture.delayedExecutor()의 내부 동작

🔍 내부적으로 하는 일

1️⃣ 비동기 작업을 실행할 Executor를 생성
2️⃣ 내부적으로 ScheduledThreadPoolExecutor를 사용하여 delay 후 실행
3️⃣ CompletableFuture.runAsync() 또는 supplyAsync()와 함께 사용 가능
💡 즉, 실행 스레드를 바로 할당하지 않고, delay만큼 기다렸다가 실행을 예약하는 역할을 합니다.

delayedExecutor() 사용 예제

1️⃣ 기본적인 비동기 실행 예약

Executor delayedExecutor = CompletableFuture.delayedExecutor(2, TimeUnit.SECONDS); CompletableFuture.runAsync(() -> { System.out.println("2초 후 실행됨!"); }, delayedExecutor);
📌 설명:
  • CompletableFuture.delayedExecutor(2, TimeUnit.SECONDS)를 사용하여 2초 후 실행되도록 예약.
  • 바로 실행되지 않고, 2초 후에 실행됨.

2️⃣ supplyAsync()와 함께 사용

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "5초 후 완료!"; }, CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS)); future.thenAccept(System.out::println);
📌 설명:
  • supplyAsync()5초 후에 실행하도록 예약.
  • thenAccept(System.out::println)을 통해 실행이 완료되면 결과를 출력.
결과:
(5초 대기) 5초 후 완료!

3️⃣ 특정한 Executor에서 실행하기

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); CompletableFuture.runAsync(() -> { System.out.println("3초 후 실행됨!"); }, CompletableFuture.delayedExecutor(3, TimeUnit.SECONDS, scheduler));
📌 설명:
  • 기본적으로 delayedExecutor()는 내부적으로 ForkJoinPool.commonPool()을 사용하지만,ScheduledExecutorService를 직접 제공하면 커스텀 스레드 풀에서 실행 가능.

🚀 CompletableFuture.delayedExecutor() vs Thread.sleep() 차이점

기능
CompletableFuture.delayedExecutor()
Thread.sleep()
비동기 실행 가능
✅ 가능 (스레드 블로킹 없음)
❌ 불가능 (스레드 블로킹)
스케줄링 지원
ScheduledThreadPoolExecutor 기반
❌ 단순 대기
사용 목적
✅ 특정 시간 후 실행 예약
❌ 현재 스레드 일시 정지
💡 즉, Thread.sleep()은 현재 스레드를 블로킹하지만, delayedExecutor()는 비동기 실행을 예약하므로 더 효율적!

🎯 정리

CompletableFuture.delayedExecutor()는 특정 시간 후에 비동기 작업을 예약하는 기능
✅ 내부적으로 ScheduledThreadPoolExecutor를 사용하여 일정 시간 후 실행
Thread.sleep()과 달리 현재 스레드를 블로킹하지 않음
멀티 스레드 환경에서 delayedExecutor()를 사용하면 효율적인 비동기 지연 실행 가능 🚀

추가 질문이 있으면 언제든지 물어봐 주세요! 😊