Java 초보도 이해하는 비동기, 병렬 처리, 체이닝 그리고 AsyncChain<T>의 역할

2025. 7. 2. 16:23Spring

반응형

Java로 프로젝트를 하다 보면 CompletableFuture, 비동기, 체이닝, 병렬 처리 같은 용어를 자주 듣게 됩니다. 처음에는 어렵게 느껴지지만, 실제 개념은 꽤 간단합니다. 이번 글에서는 이 개념들을 아주 쉽게 설명하고, 실제 현업에서 어떻게 활용되는지 보여드리겠습니다. 마지막에는 이 모든 개념을 더 쉽게 사용할 수 있게 도와주는 AsyncChain<T> 클래스도 함께 소개할게요.

 

 

1️⃣ 동기(Synchronous) vs 비동기(Asynchronous)

🔸 동기 처리란?

코드가 한 줄씩 순서대로 실행되고, 앞 작업이 끝나야 다음 작업으로 넘어가는 방식입니다.

 

System.out.println("A");
Thread.sleep(1000); // 1초 멈춤
System.out.println("B");


// 출력---------------------
A
(1초 후) B

 

 

🔸 비동기 처리란?

앞 작업이 끝나기를 기다리지 않고, 다음 작업을 바로 수행합니다. 주로 CompletableFuture를 통해 구현합니다.

 

CompletableFuture.runAsync(() -> {
    try {
        Thread.sleep(1000);
        System.out.println("비동기 작업 완료");
    } catch (InterruptedException e) {}
});

System.out.println("메인 쓰레드는 계속 진행됨");

// 출력------------------------------------
메인 쓰레드는 계속 진행됨
(1초 후) 비동기 작업 완료

 

 

2️⃣ 병렬 처리란?

여러 작업을 동시에 처리하는 것을 의미합니다. 주로 CompletableFuture를 여러 개 실행하고 allof로 기다립니다.

List<Integer> numbers = Arrays.asList(1, 2, 3);

List<CompletableFuture<Void>> futures = numbers.stream()
    .map(n -> CompletableFuture.runAsync(() -> {
        System.out.println("작업: " + n);
    }))
    .collect(Collectors.toList());

CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();


// 결과는 실행 순서에 상관없이 "작업: 1", "작업: 2", "작업: 3"이 동시에 출력됩니다.

 

 

3️⃣ 체이닝(Chaining)이란?

비동기 작업들을 순차적으로 연결해서 실행하는 방식입니다. 앞의 결과를 다음 작업에 넘길 수 있어요.

덕분에 코드가 더 간결하고 읽기 쉬워집니다.

CompletableFuture.supplyAsync(() -> 10)
    .thenApply(x -> x * 2)       // 10 * 2 → 20
    .thenApply(x -> x + 3)       // 20 + 3 → 23
    .thenAccept(System.out::println); // 출력: 23

 

4️⃣ AsyncChain<T> 클래스 소개

Java의 CompletableFuture는 강력하지만 문법이 다소 복잡하고 가독성이 떨어질 수 있습니다. 그래서 AsyncChain<T>는 다음과 같은 목적을 가지고 만들어졌습니다.

비동기, ✅ 병렬 처리, ✅ 체이닝을 더 쉽게 사용하도록 도와주는 유틸리티 클래스입니다.

📌 기본 사용법

AsyncChain.supply(() -> 10)
    .map(x -> x * 2)                      // 20
    .flatMap(x -> AsyncChain.of(x + 5))   // 25
    .onSuccess(System.out::println);      // 출력: 25

 

📌 주요 기능 요약

기능 메서드
비동기 작업 시작 supply, of, supplyAll
값 변환 map, flatMap
병렬 처리 mapParallel, combineAll
조건 분기 filter, doIf
예외 처리 recover, orElse, onFailure
완료 후 처리 onSuccess, whenComplete
타임아웃, 재시도 timeout, retry

 

📌 병렬 처리 예시

AsyncChain.ofAll(1, 2, 3, 4)
    .mapParallel(x -> x * 2)
    .onSuccess(result -> System.out.println("결과: " + result));


// 출력 예시: 
결과: [2, 4, 6, 8] (순서는 비보장)

 

5️⃣ 실제 예시: 웹 API 비동기 처리

AsyncChain.supply(() -> userId)
    .flatMap(id -> AsyncChain.of(userRepository.findById(id))) // DB 조회
    .map(user -> user.getPoint())
    .map(point -> point * 1.1) // 포인트 계산
    .onSuccess(result -> System.out.println("최종 포인트: " + result))
    .onFailure(Throwable::printStackTrace);

 

✅ 마무리:

개념 쉬운 설명
비동기 기다리지 않고 다음 작업 먼저
병렬 처리 여러 작업을 동시에 처리
체이닝 결과를 이어서 작업 연결
AsyncChain 위 3개를 쉽게 쓰도록 도와주는 클래스

 

AsyncChain<T>는 실무에서 자주 반복되는 패턴(비동기, 체이닝, 예외 처리, 병렬 처리)을 쉽고 깔끔하게 사용할 수 있도록 만들어진 유틸리티입니다. 초보자라도 기본 개념만 이해하면 바로 활용할 수 있고, 실무 생산성도 크게 향상됩니다.

반응형