본문 바로가기
Android

CoroutineDispatcher.Main.immediate 알아보기

by 쎄오SseO 2023. 5. 31.

Dispatcher.Main.immediate 알아보기

 

안녕하세요

안드로이드 개발자가 되기 위해 노력하는 서경원입니다.

코루틴 관리를 효과적으로 하고자 공부했던 내용을 공유해보려고 합니다.

코루틴에 대한 기본적인 내용과, Dispatchers.Main.immediate, 코루틴의 동작을 담고 있습니다.


 

 

여러분들은 viewModelScope의 내부를 들여다본 적이 있으신가요??

아래는 viewModelScope의 내부 코드 입니다.

public val ViewModel.viewModelScope: CoroutineScope
    get() {
        val scope: CoroutineScope? = this.getTag(JOB_KEY)
        if (scope != null) {
            return scope
        }
        return setTagIfAbsent(
            JOB_KEY,
            CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
        )
    }

저는 viewModelScope에서 어떤 쓰레드를 사용하는 가에 대해 궁금해서 내부를 들여다본 적이 있습니다.

내부에서 보이는 것은 Dispatchers.Main.immediate 였습니다.

Dispatchers.Main은 알고 있는데 뒤에 붙은 immediate는 뭐지?

궁금증을 풀기 위해 immediate에 대해 알아보기로 하였습니다.

 

 

Dispatchers.Main.immediate

immediate를 파악하려면 코루틴이 동작하는 내부 과정을 알고 계셔야합니다.

  1. 코루틴이 생성되면 Dispatcher에게 보냅니다.
  2. Dispatcher는 코루틴의 Context에 맞게 해당 쓰레드로 보냅니다
  3. 쓰레드는 해당 코루틴을 수행합니다.

코루틴은 해당 쓰레드로 적재되는 과정을 거치게 됩니다.

immediate의 뜻인 “즉각적인”을 생각해보면 어떤 동작인지 조금 눈치채셨을 수 있습니다.

 

맞습니다. 코틀린 공식문서를 보면 이미 올바른 컨텍스트에 있는 경우에 추가 재디스패치 없이 즉시 코루틴을 실행하는 디스패처를 반환한다고 되어있습니다.

바로 실행되는 동작이라고 보시면 될 것 같습니다.

CoroutineScope(Dispatchers.Main).launch {
    println(1)
}
println(2)

위 코드를 실행하면 2가 출력된 후에 1이 출력되게 됩니다. (적재되는 과정 때문)

하지만,

CoroutineScope(Dispatchers.Main.immediate).launch {
    println(1)
}
println(2)

“즉각적”으로 실행되기 때문에 1이 출력된 후 2가 출력됩니다.

immediate를 사용하여 순서를 보장하고 최적화에 유용하게 쓰일 수 있습니다.

그렇기 때문에 lifecycleScope와 viewModelScope에서 모두 immediate를 사용하는 것 같습니다.

 

 

개선점

저희는 기존의 코드에서 CoroutineScope(Dispatchers.Main)에서 lifecycleScope로 바꾸어 쓰기로 했습니다.

순서가 보장되기 때문에 관리하기 편하기 때문이었습니다.

그리고 lifecycleScope는 생명 주기가 인식되는 Scope로 메모리 누수를 막아줄 수 있습니다

 


참고 링크

Dispatchers.Main.immediate 의 이해

[Coroutine] 3. Coroutine의 Dispatcher 란 무엇인가?

immediate