Understanding Coroutine Execution: How Kotlin Tracks Suspension, Resumption, and Completion
If you use Kotlin coroutines, a question will definitely come to your mind: “How do these coroutines manage which coroutine has finished and which one has to be resumed?” This thing is quite interesting, and today we will understand it in simple language. So let’s get started!
Internal mechanism of coroutines
Kotlin coroutines use a smart mechanism that is based on suspension and resumption. Their main work revolves around Continuation, Dispatcher, and Structured Concurrency.
1. What is Continuation?
Continuation is an object that tracks the state of each coroutine. Whenever a coroutine is suspended (such as calling a suspending function), its current execution point, local variables, and state are saved in Continuation.
When the coroutine is resumed, Continuation starts from where it was suspended. In simple words, it acts like a bookmark that remembers the progress of the coroutine.
2. Role of Dispatcher
Dispatcher decides on which thread the execution of the coroutine will take place. When a coroutine is suspended, its control is passed to the Dispatcher. The Dispatcher ensures that when the suspend condition is met (e.g., the API response is received), the coroutine is resumed.
Common Dispatchers:
Dispatchers.IO: For background tasks.
Dispatchers.Main: For UI thread.
Dispatchers.Default: For CPU-intensive tasks.
3. Structured Concurrency
Coroutines follow a parent-child relationship, which makes them organized. If a coroutine launches other coroutines (child coroutines), the parent coroutine will wait for them to complete.
The parent coroutine runs a Job that tracks the status of all child coroutines. When all the child coroutines are completed, then the parent coroutine completes its work.
How is Coroutine Execution Tracked?
- Suspension Points : When a coroutine calls a suspending function (e.g., delay(), withContext()), it is temporarily suspended. This time: 1. The state of the coroutine is saved in Continuation. 2. The thread becomes free and starts doing other tasks.
2. Resume: When the work of the suspending function is finished (e.g. the API response is received or the delay is completed), the Dispatcher resumes our coroutine. Continuation resumes our coroutine from where it was suspended.
3. Parent-Child Tracking: If a parent coroutine launches multiple child coroutines, that parent coroutine’s Job tracks the status of all. When all the child coroutines are completed, then the parent coroutine also completes its work.
Let us understand with an example.
Here is a simple example that shows suspension and resume:
import kotlinx.coroutines.*
fun main() = runBlocking {
println("Parent coroutine starts")
val job1 = launch {
println("Child coroutine 1 starts")
delay(1000) // Suspend here
println("Child coroutine 1 finishes")
}
val job2 = launch {
println("Child coroutine 2 starts")
delay(500) // Suspend here
println("Child coroutine 2 finishes")
}
job1.join() // Wait for job1 to complete
job2.join() // Wait for job2 to complete
println("Parent coroutine finishes")
}
Output:
Parent coroutine starts
Child coroutine 1 starts
Child coroutine 2 starts
Child coroutine 2 finishes
Child coroutine 1 finishes
Parent coroutine finishes
Explanation:
- Coroutines are suspended at delay(1000) and delay(500).
2. When the delay is complete, Continuation resumes them.
3. join() ensures that the parent coroutine waits for its child coroutines to complete.
Real-World Example: API Calls
Coroutines are perfect for managing asynchronous API calls. see how:
import kotlinx.coroutines.*
suspend fun fetchDataFromApi(): String {
delay(1000) // Simulate network delay
return "API Response"
}
fun main() = runBlocking {
println("Fetching data...")
val data = async {
fetchDataFromApi() // Suspend here
}
println("Data received: ${data.await()}")
}
Conclusion:
The internal mechanism of coroutines makes them powerful and efficient. The combination of Continuation, Dispatcher, and Structured Concurrency ensures that coroutines are correctly suspended and resumed. Now you can use this knowledge confidently in your projects and interviews!
Please let me know your suggestions and comments. Follow for more such easy and helpful tutorials.
Thanks for reading…
Happy Coding!