반응형

안드로이드에는 아래와 같이 네 개의 Dispatcher가 있습니다.

- Default

- Main

- Unconfined

- IO

 

그런데 Dispatcher가 뭘까요?

 

안드로이드 공식문서에서는 다음과 같이 Dispatcher에 대해 소개하고 있습니다.

Kotlin coroutines use dispatchers to determine which threads are used for coroutine execution.

 코루틴은 실행하기 위해서 Dispatcher를 이용해 실행할 thread를 정한다고 합니다. 다시 말해서, Dispatcher.Main은 Thread가 Main Thread를 정하게끔 도와주는 것이지, Main Thread를 의미하는 것은 아닙니다.

 

 이어서 위에서 말씀드렸던 네 개의 Dispatcher에 대해 설명해봅니다.

* Dispatcher.Default

- launch, async와 같은 기본적인 builder들의 default dispatcher입니다.

- default로 CPU core 개수만큼 동시에 돌릴 수 있으며, 최소 두개로 돕니다.

- Main Thread가 아닌 Thread에서 CPU 작업을 하기 위해 만들어졌습니다. 

- 리스트를 정렬하고 Json을 parsing할 때 사용할 수 있습니다.

 

* Dispatcher.Main

- UI 작업을 위한 Main Thread로 이동시키는 Coroutine Dispatcher입니다. 위에서도 말씀드렸지만, Dispatcher.Main은 Main Thread가 아닙니다. 안드로이드 공식문서에서도 Dispatchers.Main으로 하여금 coroutine이 main thread에서 돌 수 있도록 하라고 제시하고 있습니다. (Use this dispatcher to run a coroutine on the main Android thread. 링크)

 

* Dispatcher.Unconfined

- 특정 Thread로 넣어야할 지 정해지지 않은 Coroutine Dispatcher입니다. 

- Dispatcher.Unconfined는 호출 Thread에서 코루틴을 시작합니다.

- 다시 suspend 함수가 실행(resume)될 때, 다시 suspend 함수를 실행한 Thread에서 수행됩니다. 

- Unconfined Dispatcher는 coroutine이 cpu 시간을 소모하지 않거나 UI를 업데이트하지 않는 경우처럼 특정 Thread에 국한된 작업이 아닌 경우 적절합니다.

 

* Dispatcher.IO

- 파일 읽기, 파일 쓰기, 소켓 읽기와 같이 blocking IO를 할 때 이 IO Dispatcher를 활용합니다.

- Thread의 개수가 늘어날 수도 있고, 필요에 따라서는 종료되고 줄어들 수 있습니다.

- System 영역의 "kotlinx.coroutines.io.parallelism"에 명시된 Thread의 개수만큼 늘어날 수 있습니다. Default로는 64개의 Thread까지 생성이 가능합니다. System에 명시된 Thread보다 더 필요하다면 custom하게 만들어 사용하면 됩니다.

- IO Dispatcher는 Default Dispatcher와 Thread를 공유합니다. 따라서 withContext(Dispatcher.IO) { ... }를 사용하는 것이 실제로 다른 Thread로 전환하는 것은 아니며 같은 Thread에서 동작하게 됩니다. 아래 코드를 확인해봅시다.

 Thread.currentThread().name을 통해 현재 Thread를 확인할 수 있습니다. CoroutineScope 내부에서 작동한 작업들은 비동기로 작업하기 때문에 순서를 보장하지 않습니다. 이 때 로그를 확인해보시면, Default가 1번 Thread에서 두 번 찍히고, IO Thread가 1번 Thread와 2번 Thread에서 각각 한번씩 찍힌 것을 확인할 수 있습니다. 다시 말해서 Dispatcher.Default와 Dispatcher.IO는 Thread를 공유하고 있음을 알 수 있습니다. 아래는 코틀린 공식 문서의 내용입니다.

This dispatcher shares threads with a Default dispatcher, so using withContext(Dispatchers.IO) { ... } does not lead to an actual switching to another thread — typically execution continues in the same thread. As a result of thread sharing, more than 64 (default parallelism) threads can be created (but not used) during operations over IO dispatcher.

 

반응형

+ Recent posts