Coroutines Fundamentals
An introduction to Kotlin's suspend functions and coroutines for asynchronous code.
What you'll learn
- Explain what a suspend function is and why it's needed for asynchronous code
- Describe conceptually how a coroutine differs from a traditional thread
- Recognize launch and runBlocking as ways to start coroutine execution
Explanation
Kotlin's concurrency model is built on coroutines -- lightweight units of concurrent execution that can be paused and resumed without blocking the underlying thread. A function that can pause is marked suspend: suspend fun fetchData(): String { ... } -- this marks it as a function that may suspend execution (e.g. while waiting for network I/O) without blocking the thread it's running on.
A key conceptual difference from a traditional OS thread: a single thread can run many coroutines, switching between them at suspension points, which is far cheaper than creating a new thread per concurrent task -- similar in spirit (though technically different in implementation) to Go's goroutines from earlier language comparisons if you've seen those.
You start a coroutine with a coroutine builder like launch (fire-and-forget, inside a CoroutineScope) or, in simple example/test code, runBlocking (which blocks the current thread until the coroutine inside it completes -- mainly used to bridge into coroutine code from regular, non-suspending code, like a program's main function).
This is an introductory conceptual overview -- production coroutine code (structured concurrency, dispatchers, cancellation) is a deeper topic beyond this fundamentals course's scope.
Guided lab
Predict: A suspend function bridged via runBlocking
Read this program (using kotlinx.coroutines' runBlocking and delay) and predict exactly what it prints, in order.
import kotlinx.coroutines.*
suspend fun fetchGreeting(): String {
delay(100) // simulates a non-blocking wait, e.g. for network I/O
return "Hello from a coroutine!"
}
fun main() = runBlocking {
println("Before fetch")
val greeting = fetchGreeting()
println(greeting)
println("After fetch")
}Stuck? Get a hint.
Common mistakes
- Calling a suspend function directly from regular (non-suspend) code without a coroutine builder like launch or runBlocking -- it won't compile.
- Assuming a coroutine is the same as an OS thread -- many coroutines can run on one thread, switching at suspension points.
- Using runBlocking in production code paths instead of just examples/tests/bridging code -- it blocks the calling thread, defeating the point of coroutines' non-blocking nature.
Knowledge check
Takeaway
suspend functions can pause without blocking their thread; many coroutines can share one thread; use runBlocking mainly to bridge into coroutine code from regular code.
Summary
Coroutines are lightweight, pausable units of concurrency built on suspend functions, started via builders like launch or runBlocking -- introductory concepts only in this course.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.