Intermediate 8 min readKotlin 2.0

Kotlin Dispatchers โ€” Choosing the Right Thread

Dispatchers control which thread pool runs your coroutine. Use Main for UI, IO for blocking I/O, and Default for CPU work.

What You Will Learn

  • Main vs IO vs Default dispatchers
  • Switch context with withContext
  • Keep UI updates on the main thread
  • Run network and disk work on IO
  • Avoid blocking the main dispatcher

Common Dispatchers

Dispatchers.Main โ€” UI thread on Android. Dispatchers.IO โ€” optimized for blocking I/O. Dispatchers.Default โ€” CPU-intensive work. Dispatchers.Unconfined โ€” inherits caller thread (rare in app code).

withContext Switches Threads

kotlin
import kotlinx.coroutines.*

suspend fun loadData(): String = withContext(Dispatchers.Default) {
    // simulate CPU work
    "Loaded"
}

fun main() = runBlocking {
    println(loadData())
}
Output
Loaded

withContext runs the block on Default and returns the result. The caller resumes on its original dispatcher.

Dependency required: implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")

IO for Network and Files

Never perform blocking network or file calls on Main. Wrap them in withContext(Dispatchers.IO) { }.

IO Dispatcher Pattern

kotlin
import kotlinx.coroutines.*

suspend fun readFromDisk(): String = withContext(Dispatchers.IO) {
    delay(100) // stands in for file read
    "file contents"
}

fun main() = runBlocking {
    println(readFromDisk())
}
Output
file contents

The blocking-style work runs on the IO pool, keeping other dispatchers responsive.

Best Practice: On Android, collect flows on Main but perform repository I/O on Dispatchers.IO.

Practice Exercise

Exercisemultiple choice

Which dispatcher is best for reading a large file from disk?

Quick Quiz

Quick Quiz

What does withContext(Dispatchers.IO) { } do?

Frequently Asked Questions

Related Tutorials

Last updated: 2026-05-19Kotlin 2.0

Written by KotlinGuide Editorial Team ยท Reviewed by KotlinGuide Technical Review