Coroutine context and dispatchers – 1. Dispatchers and threads

코틀린의 코루틴 컨텍스트는 코루틴 디스패처(CoroutineDispatcher) 를 포함하고 있습니다. 이 디스패처는 코루틴을 실행하기 위해 어느 스레드를 사용할 것인지를 결정하는 역할을 합니다. 코루틴 디스패처는 코루틴의 실행을 특정 스레드로 제한할 수 있고, 이를 스레드 풀로 전달하거나 특정 스레드에 제한되지 않도록 두기도 합니다.

launch, async 등의 모든 코루틴 빌더는 옵셔널하게 CoroutineContext 를 매개변수로 받습니다. 이 매개변수는 코루틴이나 다른 컨텍스트 요소들을 위해 특정 디스패처를 명시하는 용도로 사용됩니다.

다음 예제 코드를 살펴봅시다.

 

launch { // context of the parent, main runBlocking coroutine
    println("main runBlocking      : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
    println("Unconfined            : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher 
    println("Default               : I'm working in thread ${Thread.currentThread().name}")
}
launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
    println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}")
}

여기를 클릭해 전체 코드를 볼 수 있습니다.

 

앞의 예제 코드는 다음과 같은 결과를 출력합니다.

 

Unconfined            : I'm working in thread main
Default               : I'm working in thread DefaultDispatcher-worker-1
newSingleThreadContext: I'm working in thread MyOwnThread
main runBlocking      : I'm working in thread main

 

매개변수 없이 launch { … } 가 실행되면 이 코루틴은 이를 호출한  CoroutineScope 로부터 컨텍스트(와 디스패처)를 상속받습니다. 예제의 코드에서는 메인 스레드에서 실행되는 runBlocking 코루틴을 상속받습니다.

Dispatchers.Unconfined 는 조금 다른 방식으로 동작하는 특별한 디스패처입니다. 이에 대해서는 다음에 별도로 설명하겠습니다.

코루틴이 GlobalScope 에서 실행될 때에 사용되는 디폴트 디스패처는 Dispatchers.Default 로 백그라운드 스레드 풀을 이용합니다. 결국 launch(Dispatchers.Default) { … } 는 GlobalScope.launch { … } 와 같습니다.

newSingleThreadContext 는 코루틴이 실행될 새로운 스레드를 생성합니다. 이렇게 생성된 전용 스레드는 상대적으로 많은 리소스를 필요로 합니다. 실제 어플리케이션에서는 이 스레드가 필요하지 않게 되면 명시적으로 종료시켜주거나 전역변수에 두고 재사용하도록 합니다.

Leave a Comment

Your email address will not be published. Required fields are marked *