Coroutine context and dispatchers help control where and how coroutines run. They decide the thread or thread pool used for running tasks.
Coroutine context and dispatchers in Kotlin
launch(Dispatchers.IO) {
// code to run in IO dispatcher
}
launch(Dispatchers.Main) {
// code to run on main thread
}
val context = Dispatchers.Default + CoroutineName("MyCoroutine")Dispatchers.IO is for input/output tasks like files or network.
Dispatchers.Main runs on the main thread, good for UI updates.
launch(Dispatchers.Default) {
println("Running on Default dispatcher")
}launch(Dispatchers.IO) {
println("Running on IO dispatcher")
}launch(Dispatchers.Main) {
println("Running on Main dispatcher")
}val context = Dispatchers.Default + CoroutineName("MyCoroutine") launch(context) { println("Coroutine with a name") }
This program launches two coroutines each on a different dispatcher. It prints the thread name to show where each runs. The Dispatchers.Main coroutine is commented out because it requires platform support.
import kotlinx.coroutines.* fun main() = runBlocking { launch(Dispatchers.Default) { println("Default dispatcher: Running on thread ${Thread.currentThread().name}") } launch(Dispatchers.IO) { println("IO dispatcher: Running on thread ${Thread.currentThread().name}") } // Dispatchers.Main requires platform support (e.g., Android). It may cause errors on JVM console apps. // launch(Dispatchers.Main.immediate) { // println("Main dispatcher: Running on thread ${Thread.currentThread().name}") // } }
Dispatchers.Main requires platform support (like Android). On JVM console apps, it may cause errors.
You can combine multiple context elements using the + operator.
Use runBlocking in main functions to wait for coroutines to finish.
Coroutine context controls where coroutines run.
Dispatchers specify the thread or thread pool for coroutines.
Use Dispatchers.Main for UI, Dispatchers.IO for IO tasks, and Dispatchers.Default for CPU work.
Practice
Solution
Step 1: Understand dispatcher roles
Dispatchers.Default is designed for CPU-intensive work like calculations.Step 2: Match task type to dispatcher
Heavy CPU tasks should use Dispatchers.Default to avoid blocking UI or IO threads.Final Answer:
Dispatchers.Default -> Option AQuick Check:
CPU work = Dispatchers.Default [OK]
- Using Dispatchers.IO for CPU tasks
- Using Dispatchers.Main for background work
- Confusing Dispatchers.Unconfined with Default
Solution
Step 1: Identify correct dispatcher name
Dispatchers.IO is the correct dispatcher for IO tasks.Step 2: Check syntax correctness
launch(Dispatchers.IO) { /* code */ } is valid Kotlin coroutine syntax.Final Answer:
launch(Dispatchers.IO) { /* code */ } -> Option DQuick Check:
IO dispatcher syntax = launch(Dispatchers.IO) { /* code */ } [OK]
- Using non-existent Dispatchers.Background
- Mixing up Dispatchers.Default and Dispatchers.IO
- Forgetting braces or parentheses
import kotlinx.coroutines.*
fun main() = runBlocking {
launch(Dispatchers.Default) {
println("Running on: " + Thread.currentThread().name)
}.join()
}Solution
Step 1: Identify dispatcher thread naming
Dispatchers.Default uses a shared pool named like DefaultDispatcher-worker-n.Step 2: Check printed thread name
The coroutine runs on a background thread named DefaultDispatcher-worker-1 or similar.Final Answer:
Running on: DefaultDispatcher-worker-1 -> Option AQuick Check:
Default dispatcher thread name = Running on: DefaultDispatcher-worker-1 [OK]
- Assuming it runs on main thread
- Confusing IO dispatcher thread names
- Expecting Unconfined dispatcher output
fun main() = runBlocking {
launch(Dispatchers.Main) {
println("Hello from Main")
}
}Solution
Step 1: Understand Dispatchers.Main requirements
Dispatchers.Main requires a UI thread environment (like Android or JavaFX).Step 2: Check runBlocking context
runBlocking runs on the main thread but usually outside UI context, so Dispatchers.Main is invalid here.Final Answer:
Dispatchers.Main cannot be used in runBlocking without a UI environment -> Option BQuick Check:
Main dispatcher needs UI thread = Dispatchers.Main cannot be used in runBlocking without a UI environment [OK]
- Assuming Dispatchers.Main works everywhere
- Forgetting to join coroutine before main ends
- Thinking println is disallowed in coroutines
Solution
Step 1: Identify correct dispatcher for network request
Network requests should run on Dispatchers.IO to avoid blocking the main thread.Step 2: Switch to Main dispatcher for UI update
UI updates must happen on Dispatchers.Main to safely update UI components.Step 3: Analyze code structure
launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } correctly uses Dispatchers.IO for fetching and withContext(Dispatchers.Main) for UI update.Final Answer:
launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } -> Option CQuick Check:
IO for network + Main for UI = launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } [OK]
- Updating UI on IO or Default dispatcher
- Running network request on Main dispatcher
- Not switching context before UI update
Ready to prove it?
Pass the test and this pattern moves unknown
