What if your program could juggle many tasks smoothly without getting tired or slow?
Coroutines vs threads mental model in Kotlin - When to Use Which
Imagine you have many tasks to do at once, like cooking, cleaning, and answering calls. If you try to do each task fully before starting the next, you waste time waiting, like waiting for water to boil.
Using threads to handle many tasks can be slow and heavy because each thread needs its own memory and resources. Managing many threads can cause your program to slow down or crash.
Coroutines let you pause and resume tasks efficiently without needing heavy resources. They work like a smart helper who switches between tasks quickly, saving time and memory.
Thread { doTask1() }.start()
Thread { doTask2() }.start()GlobalScope.launch { doTask1() }
GlobalScope.launch { doTask2() }Coroutines enable smooth multitasking with less memory and better control, making your apps faster and more responsive.
Think of a restaurant kitchen where one chef can start cooking a dish, then while waiting for it to bake, start preparing another dish without wasting time.
Threads are like full workers needing their own space and tools.
Coroutines are lightweight helpers that share resources smartly.
Using coroutines improves efficiency and app performance.
Practice
Solution
Step 1: Understand management of coroutines and threads
Coroutines are managed by Kotlin's runtime, making them lightweight tasks.Step 2: Understand thread management
Threads are managed by the operating system and are heavier compared to coroutines.Final Answer:
Coroutines are lightweight and managed by Kotlin, threads are heavier and managed by the OS. -> Option CQuick Check:
Coroutines lightweight, threads OS-managed = A [OK]
- Confusing which manages coroutines vs threads
- Thinking coroutines are OS threads
- Assuming threads are lightweight like coroutines
Solution
Step 1: Identify coroutine launch syntax
The correct way to start a coroutine in Kotlin is using the 'launch' builder inside a coroutine scope.Step 2: Check other options for correctness
Thread { println("Hello from thread") }.start() starts a thread, not a coroutine. runBlocking { Thread.sleep(1000) } uses runBlocking with Thread.sleep, which blocks a thread. coroutineStart { println("Start") } is invalid syntax.Final Answer:
launch { println("Hello from coroutine") } -> Option DQuick Check:
launch starts coroutine = A [OK]
- Using Thread instead of launch for coroutines
- Confusing runBlocking with coroutine launch
- Using invalid coroutine syntax
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(100)
println("Coroutine finished")
}
println("Main finished")
}Solution
Step 1: Understand runBlocking and launch behavior
runBlocking blocks the main thread until its coroutine completes. The launch coroutine delays 100ms before printing.Step 2: Trace output order
"Main finished" prints immediately. After 100ms delay, "Coroutine finished" prints. runBlocking waits for launch to complete before exiting.Final Answer:
Main finished Coroutine finished -> Option AQuick Check:
runBlocking waits, delay delays launch = C [OK]
- Assuming launch runs before main print
- Ignoring delay effect
- Thinking runBlocking doesn't wait
fun main() {
launch {
println("Hello")
}
}Solution
Step 1: Check coroutine launch context
launch must be called inside a coroutine scope or suspend function. Here, main is a regular function without scope.Step 2: Identify missing coroutine scope
Without a scope like runBlocking or CoroutineScope, launch cannot start a coroutine.Final Answer:
Missing coroutine scope to launch coroutine -> Option AQuick Check:
launch needs coroutine scope = B [OK]
- Trying to launch coroutine outside scope
- Replacing launch with Thread incorrectly
- Thinking println causes error
Solution
Step 1: Understand concurrency with coroutines
Using async inside coroutines allows concurrent execution and returns Deferred results.Step 2: Compare options for efficiency and correctness
Create multiple threads and use Thread.sleep to wait for results uses threads and blocking sleep, which is heavy and inefficient. Use a single coroutine and call blocking network functions sequentially blocks sequentially, losing concurrency. Run network calls on the main thread directly blocks main thread, causing UI freeze.Final Answer:
Launch multiple coroutines with async and await their results -> Option BQuick Check:
async + await = concurrent coroutines [OK]
- Using threads with sleep instead of coroutines
- Blocking main thread with network calls
- Running network calls sequentially inside one coroutine
Ready to prove it?
Pass the test and this pattern moves unknown
