코루틴이란 무엇인가요?

김상욱·2024년 11월 18일
0

코루틴이란 무엇인가요?

코루틴(Coroutine)은 일반적인 함수와 달리 실행을 중단하고, 다시 재개할 수 있는 특수한 함수. 함수 호출을 제어하는 유연성을 제공 -> 일반적으로 비동기 프로그래밍이나 병렬 작업에서 효율적 사용.

  • 실행을 중단(suspend)할 수 있으며, 나중에 중단된 지점에서 다시 실행(resume)할 수 있습니다. 이는 일반적인 함수 호출(Call stack)에서는 불가능한 동작.
  • 동기 방식처럼 보이지만, 실제로는 비동기로 작업이 이루어지며, I/O 작업이나 시간이 오래 걸리는 작업에 유용. ex) 파일 읽기/쓰기, 네트워크 요청 등
  • 병렬 작업처럼 여러 코루틴이 독립적으로 실행되는 것처럼 보이며, 서로 협력(cooperate)하여 자원을 효율적으로 사용
  • 코루틴은 실행 중인 상태(context)를 유지하므로, 중단된 이후에도 지역 변수나 상태를 기억.

코루틴은 Lazy Evaluation: 호출되는 순간 즉시 실행되는 것이 아닌, 특정 조건이 충족되거나 호출될 때 실행.
코루틴을 중단하고 다시 실행하기 위해 yield 또는 await 같은 키워드 사용.

Java에서는 코루틴이라는 용어를 직접 사용하지는 않지만 비동기 작업을 효율적으로 수행할 수 있는 여러 가지 제공

  1. CompletableFuture
  • 비동기 작업을 수행하기 위해 사용되는 클래스. 체이닝 메서드 사용.
import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        CompletableFuture<Void> future = CompletableFuture
            .supplyAsync(() -> {
                System.out.println("비동기 작업 수행 중...");
                return "결과값";
            })
            .thenAccept(result -> System.out.println("결과: " + result));
        
        // 메인 스레드가 종료되지 않도록 기다림
        future.join();
    }
}
  1. Reactive Streams
  • 비동기 스트림 처리에 특화된 라이브러리
  • RxJava나 Project Reactor를 사용하면 코루틴과 비슷한 방식으로 데이터 처리
import io.reactivex.rxjava3.core.Observable;

public class Main {
    public static void main(String[] args) {
        Observable<String> observable = Observable.create(emitter -> {
            emitter.onNext("Hello");
            emitter.onNext("RxJava");
            emitter.onComplete();
        });

        observable.subscribe(item -> System.out.println("받은 데이터: " + item));
    }
}
  1. Project Loom
  • Java에서 본격적으로 코루틴과 유사한 "가벼운 스레드(Virtual Thread)"를 도입한 프로젝트
    : Virtual Thread는 코루틴과 비슷하게 중단점(suspend)를 지원하며, 수많은 비동기 작업을 효율적으로 처리 가능
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread virtualThread = Thread.ofVirtual().start(() -> {
            try {
                Thread.sleep(1000); // 중단점
                System.out.println("Virtual Thread 실행 완료");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        virtualThread.join();
    }
}

Java에서 코루틴을 완벽히 대체하려면 Kotlin을 사용해야 한다. 코틀린은 Java와 100% 호환성을 유지하면서 코루틴을 기본적으로 제공.


Spring & Java Backend 개발자가 실습할 수 있는 코루틴과 관련된 내용

Java는 직접적으로 "코루틴"을 지원하지 않지만, 아래의 실습 항목을 통해 코루틴과 유사한 비동기 처리 개념을 체험해볼 수 있습니다:


1. CompletableFuture로 비동기 작업 실습

  • 목적: 비동기 방식으로 데이터 처리 및 체이닝을 연습합니다.
  • 예제: 간단한 REST API 호출 시 비동기로 응답 처리.
import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            // 비동기 작업
            System.out.println("API 호출 중...");
            return "Hello, CompletableFuture!";
        }).thenApply(result -> {
            System.out.println("처리 중: " + result);
            return result.toUpperCase();
        }).thenAccept(result -> System.out.println("결과: " + result))
          .join(); // 결과가 완료될 때까지 대기
    }
}
  • 실습 아이디어:
    • 비동기 API 호출로 데이터 조회.
    • 체이닝을 통해 데이터 가공 및 결과 출력.

2. Spring WebFlux로 비동기 REST API 구현

  • 목적: Spring WebFlux를 사용해 비동기 및 논블로킹 API를 구현합니다.
  • 예제: MonoFlux를 활용한 비동기 데이터 스트림.
@RestController
public class ReactiveController {

    @GetMapping("/reactive")
    public Mono<String> reactiveEndpoint() {
        return Mono.just("Hello, WebFlux!")
                   .map(data -> data.toUpperCase());
    }
}
  • 실습 아이디어:
    • 비동기 API에서 데이터 처리 및 에러 핸들링.
    • 다중 데이터 스트림(Flux)을 활용한 실시간 처리.

3. Project Loom으로 Virtual Thread 실습 (Java 19 이상)

  • 목적: Java의 Virtual Thread를 활용해 코루틴과 유사한 작업 실행.
  • 예제: 가벼운 스레드를 사용한 동시 작업.
public class VirtualThreadExample {
    public static void main(String[] args) throws InterruptedException {
        Thread virtualThread = Thread.ofVirtual().start(() -> {
            try {
                Thread.sleep(1000); // 중단
                System.out.println("Virtual Thread 완료");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        virtualThread.join(); // 작업 대기
    }
}
  • 실습 아이디어:
    • 다중 Virtual Thread를 생성하여 동시에 실행.
    • 블로킹 작업과 Virtual Thread 비교.

4. Kotlin 코루틴 체험

  • Kotlin은 Java와 호환되며, 코루틴을 기본 지원합니다.
  • 예제: Spring Boot 프로젝트에서 Kotlin으로 코루틴 API 개발.
@RestController
class CoroutineController {
    @GetMapping("/coroutine")
    suspend fun getCoroutine(): String {
        delay(1000L) // 중단 가능
        return "Hello, Coroutine!"
    }
}
  • 실습 아이디어:
    • Kotlin 코루틴 기반 비동기 API를 Java 프로젝트에 통합.
    • launchasync를 활용한 비동기 병렬 처리.

실습을 위한 프로젝트 아이디어

  1. API 호출 최적화

    • 여러 외부 API를 호출하고 결과를 병렬로 처리 후 하나로 결합.
    • 예: 영화 데이터 수집, 날씨 API 호출.
  2. 파일 처리

    • 대용량 파일을 비동기로 읽고 가공 후 저장.
  3. 실시간 데이터 처리

    • WebFlux를 사용해 실시간 주식 가격이나 센서 데이터를 스트리밍.
  4. Virtual Thread 성능 비교

    • 기존의 Thread와 Virtual Thread를 비교하는 벤치마크.

추가 팁

  • Spring Boot와 통합: @Async 어노테이션을 활용해 비동기 처리를 간단히 구현.
  • Database 작업: CompletableFuture로 비동기 DB 조회 및 처리 실습.
  • GitHub 샘플 프로젝트: 위 실습 내용을 묶어 저장소로 관리.

이런 실습을 통해 비동기 프로그래밍과 코루틴 개념을 체험하며 Java 백엔드 개발 역량을 강화할 수 있습니다. 👍

0개의 댓글