📖 Scenario: You are building a simple Kotlin program that uses coroutines to perform tasks on different threads. This helps your app stay responsive by running work in the background.
🎯 Goal: Learn how to set up coroutine contexts and use dispatchers to control which thread your coroutine runs on.
📋 What You'll Learn
Create a coroutine scope with a specific dispatcher
Launch coroutines using different dispatchers
Print the thread name inside each coroutine to see where it runs
💡 Why This Matters
🌍 Real World
In real apps, using coroutine contexts and dispatchers helps keep the user interface smooth by running heavy tasks on background threads.
💼 Career
Understanding coroutine dispatchers is important for Kotlin developers working on Android or server applications to write efficient, responsive code.
Progress0 / 4 steps
1
Create a CoroutineScope with Dispatchers.Default
Create a variable called scope and assign it a CoroutineScope using Dispatchers.Default as the context.
Kotlin
Hint
Use CoroutineScope(Dispatchers.Default) to create the scope.
2
Launch a Coroutine on Dispatchers.IO
Using the scope variable, launch a coroutine with Dispatchers.IO as the context. Inside the coroutine, print the current thread name using Thread.currentThread().name.
Kotlin
Hint
Use scope.launch(Dispatchers.IO) { ... } and print the thread name inside.
3
Launch a Coroutine on Dispatchers.Main
Using the scope variable, launch another coroutine with Dispatchers.Main as the context. Inside this coroutine, print the current thread name using Thread.currentThread().name.
Kotlin
Hint
Use scope.launch(Dispatchers.Main) { ... } and print the thread name inside.
4
Run the Program and Print Completion Message
Add a runBlocking block to wait for the launched coroutines to finish. Inside runBlocking, launch the two coroutines again and then print "All coroutines completed" after they finish.
Kotlin
Hint
Use runBlocking with launch and join() to wait for coroutines, then print the message.
Practice
(1/5)
1. Which dispatcher should you use in Kotlin coroutines to perform heavy CPU-intensive tasks?
easy
A. Dispatchers.Default
B. Dispatchers.IO
C. Dispatchers.Main
D. Dispatchers.Unconfined
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 A
Quick Check:
CPU work = Dispatchers.Default [OK]
Hint: Use Default for CPU tasks, IO for disk/network, Main for UI [OK]
Common Mistakes:
Using Dispatchers.IO for CPU tasks
Using Dispatchers.Main for background work
Confusing Dispatchers.Unconfined with Default
2. Which of the following is the correct syntax to launch a coroutine on the IO dispatcher in Kotlin?
easy
A. launch(Dispatchers.Background) { /* code */ }
B. launch(Dispatchers.Default) { /* code */ }
C. launch(Dispatchers.Main) { /* code */ }
D. launch(Dispatchers.IO) { /* code */ }
Solution
Step 1: Identify correct dispatcher name
Dispatchers.IO is the correct dispatcher for IO tasks.
Hint: Use Dispatchers.IO exactly as shown to launch IO coroutines [OK]
Common Mistakes:
Using non-existent Dispatchers.Background
Mixing up Dispatchers.Default and Dispatchers.IO
Forgetting braces or parentheses
3. What will be the output of this Kotlin coroutine code snippet?
import kotlinx.coroutines.*
fun main() = runBlocking {
launch(Dispatchers.Default) {
println("Running on: " + Thread.currentThread().name)
}.join()
}
medium
A. Running on: DefaultDispatcher-worker-1
B. Running on: main
C. Running on: IO-thread-1
D. Running on: Unconfined
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 A
Quick Check:
Default dispatcher thread name = Running on: DefaultDispatcher-worker-1
[OK]
Hint: Default dispatcher runs on worker threads, not main [OK]
Common Mistakes:
Assuming it runs on main thread
Confusing IO dispatcher thread names
Expecting Unconfined dispatcher output
4. Identify the error in this Kotlin coroutine code snippet:
fun main() = runBlocking {
launch(Dispatchers.Main) {
println("Hello from Main")
}
}
medium
A. println is not allowed inside coroutines
B. Dispatchers.Main cannot be used in runBlocking without a UI environment
C. launch must be called with Dispatchers.Default
D. Missing join() call on launched coroutine
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 B
Quick Check:
Main dispatcher needs UI thread = Dispatchers.Main cannot be used in runBlocking without a UI environment [OK]
Hint: Use Dispatchers.Main only in UI apps with proper environment [OK]
Common Mistakes:
Assuming Dispatchers.Main works everywhere
Forgetting to join coroutine before main ends
Thinking println is disallowed in coroutines
5. You want to perform a network request in a Kotlin coroutine and then update the UI with the result. Which dispatcher combination should you use to ensure correct threading?
hard
A. launch(Dispatchers.Default) { val data = fetchData(); updateUI(data) }
B. launch(Dispatchers.Main) { val data = fetchData(); updateUI(data) }
C. launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } }
D. launch(Dispatchers.IO) { val data = fetchData(); updateUI(data) }
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 C
Quick Check:
IO for network + Main for UI = launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } [OK]
Hint: Use IO for background, switch to Main for UI updates [OK]
Common Mistakes:
Updating UI on IO or Default dispatcher
Running network request on Main dispatcher
Not switching context before UI update
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.