본문 바로가기

코루틴

[코루틴] CoroutineStart

 

CoroutineStart

코루틴의 실행 옵션

 

DEFAULT, ATOMIC, LAZY, UNDISPATCHED

public enum class CoroutineStart {
    // context에 따라 코루틴 실행을 즉시 예약
    DEFAULT,

    // 필요할 경우 lazy하게 코루틴 시작
    LAZY,

    // context에 따라 실행할 코루틴을 원자적으로 예약
    // Default와 유사하지만 코루틴은 실행을 시작하기 전에 취소될 수 없다
    ATOMIC,

    // 현재 스레드에서 첫 번째 중단 지점까지 코루틴을 즉시 실행
    UNDISPATCHED;
    
    ...
}

 

사용 방법

코루틴 빌더 함수 인자로 전달

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job { ... }

 

 

CoroutineStart Options

 

1. CoroutineStart.DEFAULT

코루틴의 기본 실행 옵션

빌더 함수를 호출한 즉시 코루틴의 실행을 Dispatcher에 예약하고 빌더 함수를 호출한 코루틴은 계속 실행

fun main() = runBlocking<Unit> {
    // launch 코루틴 실행을 Dispatcher에 즉시 예약
    launch {
        println("작업1")
    }
    // 먼저 실행
    println("작업2")
}
// 결과
작업2
작업1

 

 

2. CoroutineStart.ATOMIC

코루틴 실행 대기 상태에서 취소를 방지하기 위한 옵션

실행 대기 상태 -> 코루틴이 실행 요청되었지만 스레드로 보내지지 않은 경우
fun main() = runBlocking<Unit> {
    // 실행 대기 상태 중 취소 -> 종료
    val job = launch {
        println("작업1")
    }
    job.cancel()
    println("작업2")
}
// 결과
작업2

fun main() = runBlocking<Unit> {
    // 실행 대기 상태 중 취소 X
    val job = launch(start = CoroutineStart.ATOMIC) {
        println("작업1")
    }
    job.cancel()
    println("작업2")
}
// 결과
작업2
작업1

 

 

CoroutineStart.UNDISPATCHED

CoroutineDispatcher 작업 대기열을 거치지 않고 호출자 스레드에서 즉시 실행

fun main() = runBlocking<Unit> {
    // 호출 즉시 메인 스레드 할당되어 실행
    launch(start = CoroutineStart.UNDISPATCHED) {
        println("작업1")
    }
    println("작업2")
}
// 결과
작업1
작업2

 

Undispatched 동작

 

주의할 점

코루틴 빌더가 호출되었을 때만 바로 실행

코루틴 내부에서 일시 중단 후 재개 시 Dispatcher 거쳐 실행

fun main() = runBlocking<Unit> {
    launch(start = CoroutineStart.UNDISPATCHED) {
        println("일시 중단 전 즉시 실행")
        delay(100L)
        println("일시 중단 후 Dispatcher 거쳐 실행")
    }
}
// 결과
일시 중단 전 즉시 실행
일시 중단 후 Dispatcher 거쳐 실행

 

Undispatched 일시 중단 후 재개