본문 바로가기

Language/Kotlin

Kotlin Coroutine Scope, Context, Dispacher에 대해서

한 스레드, 프로세스에서 동시에 수백 개의 코루틴을 실행할 수 있습니다. 

하지만 기본적으로 코루틴들의 작업이 끝났는지 추적하지 않아 메모리 누수가 발생할 수 있습니다.

코틀린은 이 문제를 코루틴을 Scope안에서 실행하는 것으로 해결할 수 있습니다.

 

다음과 같은 코루틴 실행 예시를 통해서 Coroutine Scope, Context, Dispacher를 알아보겠습니다.

CoroutineScope(Dispatchers.IO).launch {
	// 코루틴이 실행할 작업
 }

 

Coroutine Scope

코루틴의 scope를 정의하는 인터페이스입니다.

또 다른 인터페이스는 GlobalScope가 있습니다.

GlobalScope은 top-level 코루틴을(앱이 전체에서 작동한다.) 실행하기 위해서 사용됩니다.

안드로이드 앱 개발에서는 GlobalScope를 거의 사용하지 않습니다.

이 둘은 Coroutine Context을 참조하는 역할을 합니다.

 

Coroutine Context

코루틴은 항상 Kotlin 표준 라이브러리에 정의된 CoroutineContext 유형의 값으로 표시되는 일부 컨텍스트에서 실행됩니다.

코루틴 컨텍스트는 다양한 요소의 집합입니다. 주요 요소는 코루틴의 JobDispatcher입니다.

 

위의 예시에서는 CoroutineScope의 context로서 우리는 Dispatchers.IO를 사용했습니다.

만약 Job instance를 CoroutineScope의 context로서 사용하고 싶은 경우 job instance의 이름을 포함하면 됩니다.

예를 들어 -> (Dispatchers.IO + job) 이렇게 명시하면 됩니다.

'+' 연산자는 다수의 코루틴 컨텍스트를 merge하는데 사용하면 됩니다.

 

CoroutineScope context에는 4가지가 있습니다.

  1. Dispatchers.IO
    • 코루틴은 공유된 스레드 풀로에 있는 백스라운드 스레드에서 작동합니다.
    • 로컬 DB와 작업할 때, 네트워크 작업 또는 파일과 관련된 작업을 할 때 사용할 것입니다.
  2. Dispatchers.Main
    • 코루틴이 메인스레드에서 실행됩니다.
    • ui 관련 함수, suspending 함수, LiveData에서 수정사항을 가져오는 함수 등 작고, 가벼운 작업들만 실행시킬 것입니다.
    • 권장사항은(best practice) 코루틴을 메인스레이드에 시작하고 백그라운드 스레드로 변경하는 것입니다.
  3. Dispatchers.Default
    • 많은 리스트를 정렬하는 작업같이 CPU 부하가(intensive) 많은 작업들을 할 때 사용할 것입니다.
  4. Dispatchers.Unconfined
    • GlobalScope와 함께 사용됩니다.
    • 코루틴이 현재 스레드에서 작동합니다. 중단되고 다시 시작되면 중단된 스레드에서 시작합니다.
    • 안드로이드 앱 개발에서는 사용하지 않는 것을 권고합니다.

Coroutine Builder

코루틴 스코프의 확장 함수로서(extension functions of coroutine scopes)으로 새로운 코 루틴을 실행하기 위해 사용됩니다.

Coroutine Builder에는 4개가 있습니다.

 

  • 1. Launch
        - 현재 스레드를 blocking하지 않고 새로운 코루틴을 실행합니다
        - Job 인스턴스를 반환하고 그 인스턴스는 코루틴에 대한 참조로 사용됩니다
        - 이 builder를  리턴 값이 없는 코루틴을 위해 사용합니다

    2. Aysnc
        - 현재 스레드를 blocking하지 않고 새로운 코루틴을 실행합니다.
        - Deferred<T>의 인스턴스를 반환한다. 값을 얻기 위해서 await()함수를 사용합니다.
    Deferred 인터페이스는 job인터페이스를 확장한 것입니다. 그래서 우리는 Deferred 인스턴스를 코루틴을 취소하는 것 같이 job처럼 사용할 수 있습니다.
        - 결과 값을 반환받고 싶은 경우에 Aysnc Builder를 사용합니다.

    3. produce
        - 요소 스트림을 만드는 코루틴을 위한 Builder이다.
        - ReceiveChannel 인스턴스를 반환합니다.

    4. runblocking
        - 다른 Coroutine Builder들과 다르게 작업이 끝날 때까지 스레드를 block합니다.
        - T 타입의 결과를 반환합니다.