Bird
Raised Fist0
Kotlinprogramming~10 mins

Coroutines vs threads mental model in Kotlin - Visual Side-by-Side Comparison

Choose your learning style10 modes available
Concept Flow - Coroutines vs threads mental model
Start Main Thread
↓
Launch Coroutine
↓
Coroutine Suspends?
Yes→Save State, Free Thread
↓
Thread Executes Other Tasks
↓
Coroutine Runs
↓
Coroutine Completes
↓
Main Thread Continues
Shows how coroutines run on threads, can suspend without blocking, freeing threads to do other work, unlike threads which block while running.
Execution Sample
Kotlin
import kotlinx.coroutines.*

fun main() {
  println("Start")
  GlobalScope.launch {
    delay(1000)
    println("Coroutine done")
  }
  println("End")
  Thread.sleep(2000) // Keep JVM alive to see coroutine output
}
Starts main thread, launches coroutine that delays without blocking, main thread prints 'End' immediately.
Execution Table
StepActionThread StateCoroutine StateOutput
1Start main functionMain thread runningNo coroutine yetStart
2Launch coroutineMain thread runningCoroutine started, runningStart
3Print 'End'Main thread runningCoroutine running (delay started)Start End
4Coroutine delays (suspends)Main thread free for other tasksCoroutine suspended, state savedStart End
5After 1 second, coroutine resumesMain thread running coroutineCoroutine resumedStart End
6Coroutine prints 'Coroutine done'Main thread running coroutineCoroutine completesStart End Coroutine done
7Main function endsMain thread endsCoroutine endedStart End Coroutine done
💡 Coroutine completes after delay, main thread is never blocked during coroutine suspension.
Variable Tracker
VariableStartAfter Step 2After Step 4After Step 6Final
Main threadRunning mainRunning main + launching coroutineRunning main (prints End)Running coroutineEnded
CoroutineNot startedStarted and runningSuspended (delay)Resumed and runningCompleted
Key Moments - 3 Insights
Why does the main thread print 'End' before 'Coroutine done'?
Because the coroutine suspends during delay (see step 4 in execution_table), freeing the main thread to continue and print 'End' immediately.
Does launching a coroutine create a new thread?
No, launching a coroutine does not create a new thread; it runs on existing threads and suspends without blocking them (see thread state in steps 2-4).
What happens to the thread when the coroutine suspends?
The thread is freed to do other work while the coroutine's state is saved (step 4), unlike a thread which would block and wait.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 4, what is the state of the coroutine?
ARunning without interruption
BSuspended with state saved
CCompleted
DNot started yet
💡 Hint
Check the 'Coroutine State' column at step 4 in the execution_table.
At which step does the main thread print 'End'?
AStep 1
BStep 2
CStep 3
DStep 6
💡 Hint
Look at the 'Output' column and find when 'End' appears.
If the coroutine did not suspend during delay, what would happen to the main thread?
AMain thread would block and wait
BMain thread would create a new thread
CMain thread would continue immediately
DMain thread would end before coroutine starts
💡 Hint
Refer to the 'Thread State' column in steps 3 and 4 to understand thread behavior during suspension.
Concept Snapshot
Coroutines run on threads but can suspend without blocking them.
Threads block when running tasks; coroutines free threads during suspension.
Launching a coroutine does not create a new thread.
Coroutines save state on suspension and resume later.
This allows efficient multitasking without many threads.
Full Transcript
This visual trace shows how Kotlin coroutines differ from threads. The main thread starts and launches a coroutine. The coroutine begins running but suspends during a delay, freeing the main thread to continue and print 'End' immediately. Later, the coroutine resumes and prints 'Coroutine done'. Unlike threads, coroutines do not block threads when suspended, enabling efficient multitasking. The variable tracker shows main thread and coroutine states changing step by step. Key moments clarify common confusions about suspension and thread usage. The quiz tests understanding of coroutine states and thread behavior during execution.

Practice

(1/5)
1. Which statement best describes the difference between Kotlin coroutines and threads?
easy
A. Both coroutines and threads are managed by the OS and have the same weight.
B. Threads are lightweight and managed by Kotlin, coroutines are heavier and managed by the OS.
C. Coroutines are lightweight and managed by Kotlin, threads are heavier and managed by the OS.
D. Coroutines and threads are the same and can be used interchangeably without difference.

Solution

  1. Step 1: Understand management of coroutines and threads

    Coroutines are managed by Kotlin's runtime, making them lightweight tasks.
  2. Step 2: Understand thread management

    Threads are managed by the operating system and are heavier compared to coroutines.
  3. Final Answer:

    Coroutines are lightweight and managed by Kotlin, threads are heavier and managed by the OS. -> Option C
  4. Quick Check:

    Coroutines lightweight, threads OS-managed = A [OK]
Hint: Coroutines are Kotlin tasks; threads are OS tasks [OK]
Common Mistakes:
  • Confusing which manages coroutines vs threads
  • Thinking coroutines are OS threads
  • Assuming threads are lightweight like coroutines
2. Which Kotlin code snippet correctly launches a coroutine?
easy
A. coroutineStart { println("Start") }
B. Thread { println("Hello from thread") }.start()
C. runBlocking { Thread.sleep(1000) }
D. launch { println("Hello from coroutine") }

Solution

  1. Step 1: Identify coroutine launch syntax

    The correct way to start a coroutine in Kotlin is using the 'launch' builder inside a coroutine scope.
  2. 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.
  3. Final Answer:

    launch { println("Hello from coroutine") } -> Option D
  4. Quick Check:

    launch starts coroutine = A [OK]
Hint: Use 'launch' to start coroutines, not Thread or unknown keywords [OK]
Common Mistakes:
  • Using Thread instead of launch for coroutines
  • Confusing runBlocking with coroutine launch
  • Using invalid coroutine syntax
3. What will be the output of this Kotlin code snippet?
import kotlinx.coroutines.*
fun main() = runBlocking {
  launch {
    delay(100)
    println("Coroutine finished")
  }
  println("Main finished")
}
medium
A. Main finished Coroutine finished
B. Coroutine finished Main finished
C. Main finished
D. Coroutine finished

Solution

  1. Step 1: Understand runBlocking and launch behavior

    runBlocking blocks the main thread until its coroutine completes. The launch coroutine delays 100ms before printing.
  2. Step 2: Trace output order

    "Main finished" prints immediately. After 100ms delay, "Coroutine finished" prints. runBlocking waits for launch to complete before exiting.
  3. Final Answer:

    Main finished Coroutine finished -> Option A
  4. Quick Check:

    runBlocking waits, delay delays launch = C [OK]
Hint: runBlocking waits; launch delays print [OK]
Common Mistakes:
  • Assuming launch runs before main print
  • Ignoring delay effect
  • Thinking runBlocking doesn't wait
4. Identify the error in this Kotlin coroutine code:
fun main() {
  launch {
    println("Hello")
  }
}
medium
A. Missing coroutine scope to launch coroutine
B. Incorrect use of println inside coroutine
C. launch should be replaced with Thread
D. No error, code runs fine

Solution

  1. 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.
  2. Step 2: Identify missing coroutine scope

    Without a scope like runBlocking or CoroutineScope, launch cannot start a coroutine.
  3. Final Answer:

    Missing coroutine scope to launch coroutine -> Option A
  4. Quick Check:

    launch needs coroutine scope = B [OK]
Hint: launch needs coroutine scope like runBlocking [OK]
Common Mistakes:
  • Trying to launch coroutine outside scope
  • Replacing launch with Thread incorrectly
  • Thinking println causes error
5. You want to perform multiple network calls concurrently without blocking the main thread. Which approach best uses Kotlin coroutines to achieve this?
hard
A. Create multiple threads and use Thread.sleep to wait for results
B. Launch multiple coroutines with async and await their results
C. Use a single coroutine and call blocking network functions sequentially
D. Run network calls on the main thread directly

Solution

  1. Step 1: Understand concurrency with coroutines

    Using async inside coroutines allows concurrent execution and returns Deferred results.
  2. 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.
  3. Final Answer:

    Launch multiple coroutines with async and await their results -> Option B
  4. Quick Check:

    async + await = concurrent coroutines [OK]
Hint: Use async/await for concurrent coroutines, not threads [OK]
Common Mistakes:
  • Using threads with sleep instead of coroutines
  • Blocking main thread with network calls
  • Running network calls sequentially inside one coroutine
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard