Skip to content
tezvyn:

What is a CoroutineDispatcher and when do you use each type?

Source: kotlinlang.orgMediumHow cards are made

What is a CoroutineDispatcher and when do you use each type?

Tests your grasp of coroutine threading. A dispatcher manages which threads a coroutine runs on. Explain Main for UI, Default for CPU-intensive work, and IO for blocking operations. A red flag is mixing up IO and Default or using Unconfined.

What's really being asked

This question assesses your practical knowledge of concurrency in Kotlin. The interviewer wants to see if you understand that coroutines don't magically solve threading issues; you still need to choose the right context for the right job. They are testing your ability to differentiate between CPU-bound work and I/O-bound work and to select the appropriate dispatcher to avoid blocking the wrong threads (especially the UI thread) and to maximize application performance.

The full answer

First, define a CoroutineDispatcher as the component that determines which thread or thread pool a coroutine executes on. It's an implementation of ContinuationInterceptor that directs the execution.

Second, describe the three main dispatchers. Dispatchers.Main is for interacting with the UI thread, which is mandatory for UI updates on Android. Dispatchers.Default is for CPU-intensive work, backed by a shared pool of threads with a size related to the number of CPU cores. Dispatchers.IO is for offloading blocking I/O operations, backed by a larger, on-demand pool of threads designed to handle many tasks that are mostly waiting.

Third, provide a clear scenario differentiating Default and IO. Use Default for tasks like processing a large bitmap, running complex calculations, or sorting a massive list in memory. Use IO for reading/writing files, making network requests with a blocking client, or querying a local database.

Fourth, briefly mention Dispatchers.Unconfined as a special-purpose dispatcher not for general use, as its thread can change unpredictably after suspensions.

The mistakes people make

Using Default and IO interchangeably. The most common red flag is suggesting Dispatchers.Default for a network call. While it might work, it's inefficient. The Default pool is sized for CPU-bound work (often equal to the number of cores). Blocking one of these threads with I/O starves the system of a resource meant for computation.

Over-recommending Dispatchers.Unconfined. Candidates who don't fully grasp dispatchers might suggest Unconfined as a "simple" option. This indicates a lack of understanding of its unpredictable nature and potential for causing subtle bugs.

Forgetting Dispatchers.Main. On Android, this is a critical failure. Any answer that doesn't explicitly mention keeping long-running work off the Main thread and using it only for UI updates is a major red flag.

What usually comes next

"How would you create a custom dispatcher with a fixed number of threads, and why?" (Answer: Dispatchers.IO.limitedParallelism(10) or newFixedThreadPoolContext. Use cases include limiting concurrent API calls to a rate-limited service or managing a resource with a fixed connection limit.)

"What is the difference between Dispatchers.Main and Dispatchers.Main.immediate?" (Answer: immediate tries to run immediately if already on the main thread, avoiding posting to the event queue. Useful for optimizing state updates that need to be synchronous.)

"If Dispatchers.IO can create many threads, what stops it from overwhelming the system?" (Answer: It has a configurable limit, defaulting to the greater of 64 or the number of cores. It also reuses threads from its pool.)

A concrete example

Imagine an image editing app. When a user applies a complex filter, you'd launch a coroutine on Dispatchers.Default to perform the pixel calculations, as this is pure CPU work. The resulting Bitmap would then be passed back to a coroutine on Dispatchers.Main to be displayed in an ImageView. If the app also downloads images from a URL, that download task would run on Dispatchers.IO, because it spends most of its time waiting for network data, a classic blocking I/O operation.

Interview question

Your coroutine performs a blocking network call. Which dispatcher is most suitable to ensure CPU-bound tasks are not starved of their dedicated threads?

  • a.Dispatchers.Default
  • b.Dispatchers.Main
  • c.Dispatchers.Unconfined
  • d.Dispatchers.IOCorrect
Why?

Dispatchers.IO is backed by a large thread pool designed for blocking I/O. Using Dispatchers.Default would block a thread from a smaller pool sized for CPU-intensive work, starving computation.

Just read this? Test yourself on what you have been reading.

Read the original → kotlinlang.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on kotlin — each one lists the topics its interview covers.

See open roles