Files
kotlin-examples/docs/07_코루틴.md
2025-02-22 01:33:42 +09:00

7.0 KiB

코틀린의 코루틴과 비동기 프로그래밍

코틀린은 코루틴(Coroutines) 을 통해 비동기(Asynchronous) 프로그래밍을 쉽고 직관적으로 구현할 수 있다.
코루틴은 스레드보다 가볍고 효율적이며, 콜백 지옥을 피할 수 있는 강력한 기능을 제공한다.

이 글에서는 코루틴의 개념과 주요 기능을 설명하고,
비동기 프로그래밍을 구현하는 예제를 함께 살펴보겠다. 🚀


1. 비동기 프로그래밍이란?

비동기 프로그래밍은 작업이 완료될 때까지 기다리지 않고 다음 코드를 실행하는 방식이다.
즉, 시간이 오래 걸리는 작업(예: 네트워크 요청, 파일 I/O 등) 도 프로그램이 멈추지 않고 실행된다.

1.1. 전통적인 방식 (콜백 지옥)

자바에서는 비동기 작업을 콜백(callback) 방식으로 처리해야 한다.
콜백이 중첩되면 콜백 지옥(Callback Hell) 이 발생할 수 있다.

자바의 콜백 예제

void fetchData(Callback callback) {
    new Thread(() -> {
        try {
            Thread.sleep(2000); // 2초 대기 (네트워크 요청 가정)
            callback.onSuccess("데이터를 가져왔습니다!");
        } catch (InterruptedException e) {
            callback.onError(e);
        }
    }).start();
}

interface Callback {
    void onSuccess(String data);
    void onError(Exception e);
}

public static void main(String[] args) {
    fetchData(new Callback() {
        @Override
        public void onSuccess(String data) {
            System.out.println(data);
        }

        @Override
        public void onError(Exception e) {
            System.out.println("에러 발생: " + e.getMessage());
        }
    });
}
  • fetchData() 가 비동기적으로 데이터를 가져오지만, 콜백을 계속 중첩해서 작성해야 한다.
  • 코드가 복잡해지고 가독성이 나빠지는 문제가 있다.

2. 코루틴이란?

코루틴(Coroutines)비동기 프로그래밍을 간결하고 가독성 높게 구현할 수 있도록 도와준다.
코루틴을 사용하면 콜백 없이도 순차적인 코드 스타일비동기 작업을 작성할 수 있다.

코루틴의 특징:

  • 스레드보다 가벼움 (필요할 때만 실행되고, 자동으로 일시 중단됨)
  • 순차적 스타일로 작성 가능 (콜백 없이 비동기 코드 작성 가능)
  • 비동기 코드가 직관적이고 읽기 쉬움

3. 코틀린에서 코루틴 사용하기

3.1. 기본적인 코루틴 사용

import kotlinx.coroutines.*

fun main() = runBlocking {  // 코루틴 블록 시작
    launch {  
        delay(1000L)  // 1초 대기
        println("코루틴 실행!")
    }
    println("메인 함수 실행")
}

출력 결과:

메인 함수 실행
코루틴 실행!
  • runBlocking {}: 메인 함수에서 코루틴을 실행하는 블록
  • launch {}: 새로운 코루틴을 실행
  • delay(1000L): 1초 동안 비동기 대기 (스레드 차단 없이 실행 가능)

4. 코루틴 빌더 (launch vs async)

코루틴을 실행할 때는 launchasync 를 사용할 수 있다.

빌더 반환값 특징
launch 없음 (Job 반환) 단순히 코루틴을 실행
async Deferred<T> 반환 결과 값을 반환하는 비동기 작업

4.1. launch 사용 예시 (결과 값 없음)

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000L)
        println("launch: 비동기 작업 완료!")
    }
}
  • launch {} 는 단순히 비동기 작업을 실행하고, 결과를 반환하지 않음.
  • Job 객체를 반환하지만, 보통 join()을 호출하지 않는 이상 결과를 기다리지 않음.

4.2. async 사용 예시 (결과 값 반환)

import kotlinx.coroutines.*

fun main() = runBlocking {
    val result = async {
        delay(1000L)
        "async: 비동기 작업 완료!"
    }
    println(result.await())  // 결과 값을 기다림
}
  • async {}결과 값을 반환하는 비동기 작업을 실행.
  • await() 을 호출해야 실제 값을 가져올 수 있음.

5. 여러 개의 비동기 작업 실행 (async 활용)

비동기 작업을 병렬로 실행하려면 async {} 를 여러 개 실행하면 된다.

import kotlinx.coroutines.*

fun main() = runBlocking {
    val time = measureTimeMillis {
        val job1 = async { fetchData(1) }
        val job2 = async { fetchData(2) }
        println(job1.await())  
        println(job2.await())  
    }
    println("총 실행 시간: $time ms")
}

suspend fun fetchData(id: Int): String {
    delay(1000L)  // 네트워크 요청 시뮬레이션
    return "데이터 $id 가져옴"
}

출력 결과:

데이터 1 가져옴
데이터 2 가져옴
총 실행 시간: 1003 ms
  • async {} 로 실행된 두 개의 코루틴이 병렬로 실행됨.
  • await() 를 호출하면 해당 코루틴이 완료될 때까지 기다림.
  • 실행 시간은 1초 내외 (동시 실행되었기 때문).

6. suspend 함수 사용하기

코루틴에서 비동기 함수를 만들려면 suspend 키워드를 사용해야 한다.

suspend fun fetchData(): String {
    delay(1000L)  // 1초 대기
    return "데이터 가져옴"
}

fun main() = runBlocking {
    val data = fetchData()
    println(data)
}
  • suspend 함수는 코루틴 내에서만 실행 가능
  • delay() 같은 비동기 함수 호출 가능

7. 예외 처리 (try-catch 활용)

코루틴에서도 예외 처리를 try-catch 로 할 수 있음.

import kotlinx.coroutines.*

fun main() = runBlocking {
    try {
        val result = async { errorTask() }.await()
        println(result)
    } catch (e: Exception) {
        println("예외 발생: ${e.message}")
    }
}

suspend fun errorTask(): String {
    delay(500L)
    throw RuntimeException("오류 발생!")
}

출력 결과:

예외 발생: 오류 발생!
  • try-catch 를 사용하면 비동기 코드에서도 예외를 안전하게 처리 가능.

8. 정리

기능 자바 코틀린
비동기 실행 콜백 기반 코루틴 기반 (launch, async)
가독성 콜백 중첩 발생 순차적 코드 스타일
예외 처리 예외 전달 어려움 try-catch 사용 가능
실행 효율 스레드 사용 가벼운 코루틴 사용

코루틴을 사용하면:
비동기 코드가 더 간결하고 직관적
콜백 지옥 없이 순차적 스타일로 작성 가능
스레드보다 가볍고 효율적

코틀린에서 비동기 프로그래밍을 쉽게 구현하려면 코루틴을 적극 활용하자! 🚀