Pink Spider/Spring Boot 비동기 프로그래밍:Future 패턴

Created Tue, 27 Jan 2026 11:25:18 +0900 Modified Tue, 27 Jan 2026 10:57:58 +0900
888 Words 4 min

Spring Boot(또는 Java)에서 Future 패턴은 비동기 프로그래밍을 위한 핵심 디자인 패턴입니다. 쉽게 말해, **“지금 당장 결과를 줄 수는 없지만, 미래의 어느 시점에 작업이 완료되면 결과물을 넘겨주겠다”**는 약속(Promise)과 같습니다.


1. Future 패턴의 핵심 개념

일반적인 동기(Synchronous) 방식에서는 작업이 끝날 때까지 스레드가 아무것도 못 하고 기다려야 합니다(Blocking). 반면, Future 패턴을 사용하면 작업을 별도의 스레드에 맡기고 메인 스레드는 자기 할 일을 계속할 수 있습니다.

주요 특징

  • 비차단(Non-blocking): 결과가 나올 때까지 기다리지 않고 다른 작업을 수행할 수 있어 효율적입니다.
  • 지연 실행: 결과가 실제로 필요한 시점까지 데이터 계산을 미룰 수 있습니다.
  • 결합성: 여러 비동기 작업의 결과를 합치거나, 순차적으로 실행하는 흐름을 만들 수 있습니다.

2. Spring Boot에서의 구현 방식

Spring Boot에서는 주로 CompletableFuture@Async 어노테이션을 조합하여 이 패턴을 구현합니다.

@Async 어노테이션

메서드 위에 이 어노테이션을 붙이면, 해당 메서드는 Spring의 TaskExecutor에 의해 별도의 스레드에서 실행됩니다.

CompletableFuture<T>

Java 8에서 도입된 Future의 확장판입니다. 단순히 결과를 기다리는 것을 넘어, 작업 완료 후 콜백을 실행하거나 예외 처리를 하는 등 훨씬 강력한 기능을 제공합니다.

코드 예시:

@Service
public class OrderService {

    @Async
    public CompletableFuture<String> processOrder(Order order) {
        // 시간이 오래 걸리는 작업 (예: 결제 처리)
        Thread.sleep(2000); 
        return CompletableFuture.completedFuture("Order Processed: " + order.getId());
    }
}

3. Future vs CompletableFuture

특징 Future (기존) CompletableFuture (권장)
결과 확인 get() 호출 시 결과가 나올 때까지 블로킹됨 비동기 콜백(thenAccept) 지원
예외 처리 내부에서 직접 처리해야 함 exceptionally() 등 전용 메서드 제공
작업 조합 여러 Future를 묶기 어려움 thenCombine, allOf 등으로 조합 가능

4. 주의할 점

  1. Thread Pool 설정: @Async를 사용할 때는 기본 설정 대신 커스텀 ThreadPoolTaskExecutor를 설정하는 것이 운영 환경에서 안전합니다.
  2. get()의 함정: future.get()을 호출하는 순간, 결과가 나올 때까지 현재 스레드는 멈춥니다. 가급적 콜백 방식을 사용하는 것이 좋습니다.
  3. Self-invocation: 같은 클래스 내에서 @Async 메서드를 호출하면 프록시 패턴 특성상 비동기로 동작하지 않습니다.