Post

(Kotlin Coroutine) Dispatchers

Dispatcher란?

The coroutine dispatcher can confine coroutine execution to a specific thread, dispatch it to a thread pool, or let it run unconfined.
즉 코루틴이 어떤 thread(thread pool) 위에서 실행될지를 결정하는 역할.

기본 제공 Dispatchers

Dispatchers.Default

  • The default CoroutineDispatcher that is used by all standard builders like launch, async, etc if no dispatcher nor any other ContinuationInterceptor is specified in their context.
  • CPU core 수와 동일한 스레드 수로 구성된 스레드풀. core가 1개인 경우는 2개로 구성.
  • CPU bound 작업에 사용.

Dispatchers.IO

  • IO bound 작업에 사용.
  • 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. 👍 (thread switching은 비싸기 때문에. 최소화 하는 것이 좋다.)

Dispatchers.Main (MainScope())

  • 안드로이드 같은 UI 포함된 개발에서 사용. BE 개발에서는 쓸 일이 없음.
  • UI 관련 동작하는 Main thread에서 돌아가도록 한정 할 때 사용.
  • e.g., 화면 표시를 담당하는 Activity가 종료되는 경우 관련 코루틴들을 한꺼번에 종료해야 할 때

Dispatchers.Unconfined

  • A coroutine dispatcher that is not confined to any specific thread. It executes initial continuation of the coroutine in the current call-frame and lets the coroutine resume in whatever thread

thread pool 고갈 방지 (직접 thread pool, Dispatcher 생성)

  • 예를 들어 DB library가 coroutine 지원하지 않아 blocking call 인 경우, thread pool의 모든 thread가 block되어 새로운 request를 처리 할 수 없게 되는 상황을 방지해야 한다.
  • Dispatchers.IO에 던지는 것으로 시스템 전체가 block 되는 것은 막을 수 있다. 하지만, DB call로 인해 Dispatchers.IO 스레드 풀 전체가 block 되면, Dispatchers.IO를 사용하는 다른 작업(e.g., HTTP call)들도 영향을 받는다.
  • 그래서 아예 DB call을 위한 thread pool을 완전히 분리하고 싶을 수도 있다. (Dispatcher가 달라도 IO와 Default 처럼 thread pool은 share 하는 경우도 있는데, 이런 케이스는 thread pool을 완전히 독립적으로 만들어야 한다)
1
private val myDatabaseDispatcher = Executors.newFixedThreadPool(10).asCoroutineDispatcher()
1
private val myDatabaseDispatcher = Dispatchers.IO.limitedParallelism(10)  // At most 10 connections to the database
This post is licensed under CC BY 4.0 by the author.