1. 주요 핵심 키워드
코루틴을 사용하기 위해서 기본적으로 알아야 할 주요 키워드는 아래와 같습니다.
- CoroutineScope (그리고 GlobalScope)
- CoroutineContext
- Dispatcher
- launch (그리고 async)
CoroutineScope
CoroutineScope 는 말 그대로 코루틴의 범위, 코루틴 블록을 묶음으로 제어할수 있는 단위입니다.
GlobalScope 는 CoroutineScope 의 한 종류입니다. 미리 정의된 방식으로 프로그램 전반에 걸쳐 백그라운드 에서 동작합니다.
CoroutineContext
CoroutineContext 는 코루틴을 어떻게 처리 할것인지 에 대한 여러가지 정보의 집합입니다.
CoroutineContext 의 주요 요소 로는 Job 과 dispatcher 가 있습니다.
Dispatcher
Dispatcher 는 CoroutineContext 의 주요 요소 입니다.
CoroutineContext 을 상속받아 어떤 스레드를 이용해서 어떻게 동작할것인지를 미리 정의해 두었습니다.
다음은 io’19 세션 Understand Kotlin Coroutines on Android 에서 설명된 Dispatcher 의 용도 입니다.
Dispatchers.Default : CPU 사용량이 많은 작업에 사용합니다. 주 스레드에서 작업하기에는 너무 긴 작업 들에게 알맞습니다.Dispatchers.IO : 네트워크, 디스크 사용 할때 사용합니다. 파일 읽고, 쓰고, 소켓을 읽고, 쓰고 작업을 멈추는것에 최적화되어 있습니다.Dispatchers.Main : 안드로이드의 경우 UI 스레드를 사용합니다.
Dispatchers.Main 은 UI 구성하는 스레드를 메인으로 사용 하는 플랫폼에서 사용됩니다.
대표적으로 안드로이드 의 경우 메인 스레드는 UI 스레드 이고, 안드로이드에서 Dispatchers.Main 은 UI 스레드를 사용하여 동작합니다.
Dispatchers.Main 을 사용할수 없는 플랫폼도 있으며 이러한 플랫폼에서 사용할 경우, IllegalStateException 이 발생할수 있습니다.
이외에, 코루틴 공식 문서에 Dispatchers.Unconfined 도 존재합니다.
Dispatchers.Unconfined 는 다른 Dispatcher 와 는 달리 특정 스레드 또는 특정 스레드 풀을 지정하지 않습니다. 일반적으로는 사용하지 않으며 특정 목적을 위해서만 사용됩니다.
Dispatcher.Unconfined 는 이 기초 문서에서는 다루지 않습니다.
Dispatcher 에 관한 공식 문서는 이곳 에서 확인하실수 있습니다.
2. 코루틴은 이렇게 쓰면 됩니다
1. 사용할 Dispatcher 를 결정하고2. Dispatcher 를 이용해서 CoroutineScope 만들고3. CoroutineScope 의 launch 또는 async 에 수행할 코드 블록을 넘기면 됩니다.
launch 와 async 는 CoroutineScope 의 확장함수 이며, 넘겨 받은 코드 블록으로 코루틴을 만들고 실행해주는 코루틴 빌더 입니다.
launch 는 Job 객체를, async 는 Deferred 객체를 반환 하며, 이 객체를 사용해서 수행 결과를 받거나, 작업이 끝나기를 대기하거나, 취소하는 등의 제어가 가능합니다.
launch, async, Job, Deferred 의 자세한 사용법은 다음 포스트에서 알아보겠습니다.
다음은 코루틴 블록을 만들고 실행하는 가장 기본적인 코드 형태 입니다.
다음 예시는 모두 백그라운드 에서 동작 합니다
첫번째 블록처럼 CoroutineScope 를 새로 만들면 제어범위가 달라집니다.
두번째 블록처럼 launch 의 Dispatcher 를 변경하면 CoroutineScope 는 유지되면서 작업이 처리되는 스레드 만 변경됩니다.
제어범위가 다르면 다음과 같은 상황이 발생합니다.
다음 예시에서 내부 코루틴 블록은 멈추지 않습니다
기존 CoroutineScope 를 사용할지, 새로운 CoroutineScope 를 만들지 결정하는것은 코루틴 블록이 특정 상황에 어떻게 동작할 지를 결정하게 됩니다.
위 예시 에서는 외부 코루틴 블록 의 내부에서 새로운 CoroutineScope 를 만들었습니다.
이로서 외부 코루틴 블록 과 내부 코루틴 블록은 서로 제어범위가 달라집니다.
Job 객체의 cancel() 메서드는 자신이 해당하는 CoroutineScope 의 코루틴 블록을 취소시켜 멈출수 있지만, 내부 코루틴 블록은 다른 CoroutineScope 로 분리 되었기 때문에 멈출수 없습니다.
외부 코루틴 블록이 멈춰도, 내부 코루틴 블록은 끝까지 수행됩니다.
3. 코루틴 제어를 위한 주요 키워드
- launch , async
- runBlocking
- Job , Deferred
위에서 가볍게 살펴 본 바와 같이 launch, async 는 코루틴 블록을 만들며, 아직 다루지 않은 runBlocking 은 내부 작업이 종료될때까지 일시 중지 됩니다.
코루틴 블록을 제어하고 값을 전달받기 위해서는 launch 와 async 가 반환하는 Job, Deferred 객체를 사용합니다.
이 키워드 들에 대해서는 다음의 포스트에서 자세히 알아보도록 하겠습니다.
감사합니다.