본문 바로가기
Spring

kotlin coroutine 정리

by doodoom 2024. 9. 4.

1. couroutine?

Coroutine은 thread의 Background 작업을 대신할 수 있는 asynchronous/non-blocking programming을 제공하는 경량쓰레드(Light-Weight Threads)

여기서 경량(Light-Weight Threads)란?
기존 Java 쓰레드는 OS의 Java Native Interface(JNI)를 통해 커널 영역을 호출하여 OS가 커널 쓰레드를 생성하고 1:1로 매핑했다. 이때 Context Swiching을 하면 OS에서도 Context Switching이 된다.
경량 쓰레드는 OS의 쓰레드와 1:1로 매핑되지 않는다. OS의 쓰레드를 여러 경량 쓰레드가 번갈아가며 사용한다. 이때 발생하는 context swiching은 어플리케이션 단계에서 일어난다. 즉, OS의 context switching에 비해 빠르고 비용이 적다.

2. coroutine과 실제 OS thread와의 관계

Coroutine - 하나의 실행-종료 되어야 하는 일(Job) = 루틴(Routine) 개념
Co(협력,같이) + Routine(특정한 일의 실행위한 명령) 합성어
Thread - 루틴/일이 실행되는 곳(영역)

coroutine과 thread의 관계 사진

즉, 하나의 thread에 여러 개의 coroutine들이 동시에 실행할 수 있다. 그래서 coroutine은 경량 쓰레드라고 불린다.

3. coroutine 핵심 개념

Job

coroutine의 최소 실행 단위이다. 이 객체를 통해 개발자는 해당 실행의 상태를 관리, 모니터링 할 수 있다.

예를 들면 job.join을 통해 해당 job이 끝날때까지 대기할 수 있다.

private suspend fun test() {
        val job = CoroutineScope(Dispatchers.Default).launch {
            delay(1000L)
        }
        job.join()
    }

job은 자식-부모 관계(계층적)으로 생성이 가능하다. 즉, job 내부에 job을 생성할 수 있다. 그리고 자식 job은 부모 job의 상태에 의존적이다.
자세한건 공식문서 참조

CoroutineScope

코루틴의 범위, 코루틴 블록을 묶음으로 제어할 수 있는 단위.

예시 코드는 다음과 같다.

val scope = CoroutineScope(Dispatchers.Default).launch {
    // CoroutineScope 내에서 실행되는 코루틴
}

CoroutineContext

코루틴 실행 환경을 정의하는 요소.
구성 요소 : Job(각 코루틴 상태관리), Dispatcher(어느 쓰레드에서 실행할지 관리), CoroutineName(이름), CoroutineExceptionHandler(예외 처리)

 

Dispatcher

어느 쓰레드를 코루틴을 실행할지에 대한 정보를 담고있다.

  • 종류
    • Dispatchers.Main - 메인(UI) 스레드에서 동작하는 방식
    • Dispatchers.IO - 네트워크 / 디스크(파일) 작업에 사용하는 방식으로 File의 읽기/쓰기 & 소켓 읽기/쓰기 최적화
    • Dispatchers.Default - CPU 사용량이 많은 작업에 사용, 메인 스레드에서 하기엔 긴 작업들에 적합 -> Main을 제외한 IO/Default는 백그라운드 작업
    • Dispatchers.Unconfined - 해당 코루틴을 호출한 쓰레드를 사용. 중단 후 재개될때는 다른 스레드에서 재개될 수 있음. 즉, 사용할 쓰레드 풀이 고정 되지않음