IMCAT.DEV
로그인 가입
Java 고급 비동기

Java 비동기 프로그래밍 (CompletableFuture)

Java 비동기 프로그래밍 (CompletableFuture) — 고급

비동기 프로그래밍 (CompletableFuture)

1. 도입 (왜 배워야 하는가)

비동기 프로그래밍은 현대 소프트웨어 개발에서 필수적입니다. 특히, 웹 애플리케이션이나 대규모 시스템에서는 동시에 여러 작업을 처리해야 하는 경우가 많습니다. Java의 CompletableFuture는 이러한 비동기 작업을 간편하고 효율적으로 처리할 수 있는 강력한 도구입니다.

비동기 프로그래밍을 모르면, 특정 작업이 완료될 때까지 프로그램이 멈춰버리는 동기식 프로그래밍의 단점을 피할 수 없습니다. 예를 들어, 사용자가 웹 페이지를 요청했을 때, 웹 서버가 데이터베이스에서 데이터를 가져오는 동안 페이지가 멈춘다면 사용자 경험이 매우 나빠질 것입니다. 이럴 때 CompletableFuture를 사용하면 비동기적으로 작업을 처리하여 더 나은 성능과 사용자 경험을 제공할 수 있습니다.

2. 핵심 개념 설명

CompletableFuture는 Java의 비동기 프로그래밍을 지원하는 클래스입니다. 이를 통해 비동기 작업을 더 쉽고 직관적으로 구현할 수 있습니다.
  • 비동기(Asynchronous): 요청을 보내고 결과를 기다리지 않고 다른 작업을 수행할 수 있는 방식입니다. 예를 들어, 커피를 주문하고 기다리지 않고 친구와 대화하는 것과 같습니다.
  • Future: 비동기 작업의 결과를 나타내는 객체로, 작업이 완료될 때까지 기다릴 수 있습니다.
  • Completable: 결과가 준비되었을 때 이를 완료할 수 있는 가능성을 의미합니다.
  • 용어정의
    비동기요청 후 결과를 기다리지 않고 다른 작업 수행 가능
    Future비동기 작업의 결과를 나타내는 객체
    Completable결과가 준비되었을 때 이를 완료할 수 있는 가능성

    3. 기본 코드 예제

    아래 코드는 CompletableFuture의 가장 기본적인 사용법을 보여줍니다.

    import java.util.concurrent.CompletableFuture;
    
    public class CompletableFutureExample {
        public static void main(String[] args) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                // 2초간 작업을 시뮬레이션
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                return "작업 완료";
            });
    
            // 다른 작업을 수행
            System.out.println("비동기 작업을 시작했습니다!");
    
            // 결과를 기다림
            future.thenAccept(result -> System.out.println(result));
        }
    }

    실행 결과

    비동기 작업을 시작했습니다!
    작업 완료

    코드 한 줄씩 동작 설명

  • CompletableFuture.supplyAsync(...): 비동기적으로 실행할 작업을 정의합니다. 이 경우, 2초 후에 "작업 완료"라는 문자열을 반환합니다.
  • Thread.sleep(2000): 작업이 완료되는 데 2초 걸린다는 것을 시뮬레이션합니다.
  • System.out.println("비동기 작업을 시작했습니다!");: 비동기 작업이 시작되었음을 알리는 메시지를 출력합니다.
  • future.thenAccept(...): 비동기 작업이 완료되었을 때 실행할 작업을 정의합니다. 결과가 준비되면 "작업 완료"를 출력합니다.
  • 4. 실전 활용 예제

    예제 1: 쇼핑몰에서 장바구니 업데이트

    쇼핑몰 애플리케이션에서 사용자가 장바구니에 상품을 추가하는 경우, 데이터베이스에 상품 정보를 저장하는 작업을 비동기적으로 처리할 수 있습니다.

    CompletableFuture<Void> updateCart = CompletableFuture.runAsync(() -> {
        // 데이터베이스에 장바구니 업데이트
        System.out.println("장바구니 업데이트 중...");
        // DB 작업 시뮬레이션
        try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("장바구니 업데이트 완료");
    });
    
    // 사용자에게 진행 중임을 알림
    System.out.println("장바구니에 상품을 추가했습니다.");
    updateCart.thenRun(() -> System.out.println("장바구니가 업데이트되었습니다."));

    예제 2: 외부 API 호출

    비동기적으로 외부 API를 호출하여 데이터를 가져오는 예제입니다.

    CompletableFuture<String> fetchData = CompletableFuture.supplyAsync(() -> {
        // 외부 API 호출 시뮬레이션
        System.out.println("외부 API 호출 중...");
        try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
        return "API 데이터";
    });
    
    fetchData.thenAccept(data -> System.out.println("가져온 데이터: " + data));

    5. 흔한 실수와 주의사항

    실수 1: 예외 처리 누락

    비동기 작업에서 발생하는 예외를 처리하지 않으면 프로그램이 예기치 않게 종료될 수 있습니다.

    잘못된 코드

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
        throw new RuntimeException("예외 발생");
    });

    올바른 코드

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
        if (true) throw new RuntimeException("예외 발생");
    }).exceptionally(ex -> {
        System.out.println("예외 처리: " + ex.getMessage());
        return "기본값";
    });

    실수 2: 결과를 기다리지 않음

    비동기 작업의 결과를 처리하기 전에 메인 스레드가 종료되면 결과를 볼 수 없습니다.

    잘못된 코드

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "작업 완료");

    올바른 코드

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "작업 완료");
    future.thenAccept(result -> System.out.println(result));
    future.join(); // 메인 스레드가 결과를 기다리도록 추가

    6. 정리

  • CompletableFuture를 사용하면 복잡한 비동기 작업을 간편하게 처리할 수 있습니다.
  • 비동기 프로그래밍을 통해 애플리케이션의 성능과 사용자 경험을 향상시킬 수 있습니다.
  • 예외 처리를 적절히 구현하고, 결과를 기다리는 방법을 이해해야 합니다.
  • 다음에 학습하면 좋은 주제:

  • Reactive Programming
  • Spring WebFlux
  • 비동기 스트림 (Java 9 이상)