Coroutines and threads help your program do many things at once. Understanding their difference helps you write faster and smoother apps.
Coroutines vs threads mental model in Kotlin
import kotlinx.coroutines.* fun main() { // Launch a coroutine GlobalScope.launch { // Coroutine code here } // Create a thread Thread { // Thread code here }.start() }
Coroutines are lightweight and managed by Kotlin's library.
Threads are managed by the operating system and are heavier.
import kotlinx.coroutines.* fun main() = runBlocking { launch { println("Coroutine: Start") delay(500) println("Coroutine: End") } println("Main: Waiting") }
fun main() { val thread = Thread { println("Thread: Start") Thread.sleep(500) println("Thread: End") } thread.start() println("Main: Waiting") }
This program runs a coroutine and a thread together. The coroutine uses delay which does not block the main thread, while the thread uses Thread.sleep which blocks its own thread. The main waits for the thread to finish before ending.
import kotlinx.coroutines.* fun main() = runBlocking { launch { println("Coroutine: Start") delay(300) println("Coroutine: End") } val thread = Thread { println("Thread: Start") Thread.sleep(300) println("Thread: End") } thread.start() println("Main: Waiting") thread.join() // Wait for thread to finish }
Coroutines are much lighter than threads; you can run thousands of coroutines but only a limited number of threads.
Coroutines can pause and resume without blocking the thread they run on.
Threads are managed by the operating system and switching between them is slower and uses more memory.
Coroutines are lightweight tasks managed by Kotlin, threads are heavier OS-managed tasks.
Coroutines can pause without blocking, threads block when sleeping or waiting.
Use coroutines for efficient, smooth multitasking in Kotlin apps.
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
