liveBook · Manning

Dispatcher

As explained in Kotlin in Action, 2E

A dispatcher is a coroutine execution-context component that determines which thread or threads execute a coroutine and where its continuations are resumed.

A coroutine dispatcher decides which thread or threads execute a coroutine. Coroutines are not permanently tied to one thread: after suspension, a dispatcher may resume them on another. This makes thread choice an explicit design decision rather than an accidental property of sequential-looking suspend code. section 14.7 section 14.9

Choose a dispatcher when the work has a reason to run somewhere particular. Dispatchers.Default is the general-purpose choice for CPU-bound work and uses a pool sized to available CPU cores. Dispatchers.Main targets the UI thread supplied by a UI framework. Dispatchers.IO offloads work that calls blocking APIs. For ordinary work without a UI, blocking-IO, or confinement requirement, Default is the usual choice. section 14.7.1

Table 14.2 Dispatchers available out of the box in Kotlin coroutines (view table figure)

Dispatcher

Number of threads

Used for

Dispatchers.Default

Number of CPU cores

General-purpose operations, CPU-bound operations

Dispatchers.Main

One

UI-bound logic (“UI thread”), only when in the context of a UI framework

Dispatchers.IO

Up to 64 threads (auto-scaling) or number of CPU cores (whichever is larger)

Offloading blocking IO tasks

Dispatchers.Unconfined

- (“Whatever thread”)

Advanced cases where immediate scheduling is required (non-general-purpose)

limitedParallelism(n)

Custom (n)

Custom scenarios

Compare the built-in dispatcher choices by thread count and intended workload, including Default, Main, IO, Unconfined, and limitedParallelism(n). section 14.7.1

Start background work on Default

Pass a dispatcher to a coroutine builder: `launch(Dispatchers.Default) { log("Doing some background work") }`. The surrounding `runBlocking` code logs on the main thread, while the launched coroutine logs from a Default dispatcher worker thread. Builders such as `runBlocking`, `launch`, and `async` all accept this context argument. section 14.7.2

A child coroutine normally inherits its parent’s dispatcher, so every builder call does not need an explicit choice. To move only a portion of an existing coroutine, use `withContext` instead. A common UI pattern performs a long-running operation on Default, then uses `withContext(Dispatchers.Main)` to update the interface. Main requires a configured UI framework; switching to IO does not. section 14.7.1 section 14.7.3

Dispatcher selection does not remove concurrency responsibilities:

  • One coroutine executes sequentially, even if its dispatcher may run it on different threads over time. section 14.7.4
  • Multiple coroutines on a multithreaded dispatcher can modify shared state in parallel and lose updates. section 14.7.4
  • Protect shared critical sections with a Mutex or suitable atomic or thread-safe data structure; single-thread confinement can also avoid the race. section 14.7.4

A dispatcher is one element of a CoroutineContext, alongside lifecycle information such as a Job and optional metadata such as CoroutineName or CoroutineExceptionHandler. Passing context to a builder or `withContext` replaces the corresponding context element; combine several context elements with `+` when both a dispatcher and metadata are needed. section 14.8

How Kotlin in Action, 2E covers it

How deep it goes
Explains selection, builder arguments, withContext switching, context overrides, and shared-state hazards without detailing dispatcher implementations.
Examples
Demonstrates launching on Default, returning to Main for UI updates, inspecting context, and protecting 10,000 concurrent increments with Mutex.
What it assumes
Builds from coroutines and suspension, then introduces dispatcher inheritance and CoroutineContext composition.
What you can do after
Apply it via Kotlin coroutine builders and withContext to place work on appropriate dispatchers and protect shared state.
How it connects
Connects CoroutineContext, coroutine builders, withContext, suspending functions, thread pools, Mutex, and structured concurrency.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.