Reputation: 13
I'm trying to figure out the order of the execution of coroutine. Here is my example.
fun theCoroutineOrderWithDifferentScope() = runBlocking {
coroutineScope {
println("in the coroutineScope 1 ")
coroutineScope {
println("coroutineScope inside the coroutineScope1")
}
}
coroutineScope {
launch {
println("coroutine in the coroutineScope 2")
coroutineScope {
println("coroutineScope inside the coroutineScope2 coroutine")
}
}
println("in the coroutineScope 2")
}
launch { // #1
println("coroutine in the blocking")
}
println("in the blocking")
}
I got this result
in the coroutineScope 1
coroutineScope inside the coroutineScope1
in the coroutineScope 2
coroutine in the coroutineScope 2
coroutineScope inside the coroutineScope2 coroutine
in the blocking
coroutine in the blocking
So I conclude that it will fist execute the child scope line by line from top to down, after finish it, will start execute the parent coroutine then the child coroutine.
But after I change the order of the code block(#1) the order of the result change
fun theCoroutineOrderWithDifferentScope() = runBlocking {
coroutineScope {
println("in the coroutineScope 1 ")
coroutineScope {
println("coroutineScope inside the coroutineScope1")
}
}
launch { // #1
println("coroutine in the blocking")
}
coroutineScope {
launch {
println("coroutine in the coroutineScope 2")
coroutineScope {
println("coroutineScope inside the coroutineScope2 coroutine")
}
}
println("in the coroutineScope 2")
}
println("in the blocking")
}
the result order become like this
in the coroutineScope 1
coroutineScope inside the coroutineScope1
in the coroutineScope 2
coroutine in the blocking
coroutine in the coroutineScope 2
coroutineScope inside the coroutineScope2 coroutine
in the blocking
Why the result is not as same as result A??
I have tried search the previous questions on SOF
Upvotes: 1
Views: 52
Reputation: 15763
The behavior of coroutineScope
is:
The behavior of launch
is:
start
parameter.
The nested coroutineScopes don't launch anything so they can be removed without affecting the output, making everything a bit simpler.
Your example code only ever runs on a single thread, but some parts of your code are executed asynchronously:
For result A that means that the first coroutine is executed when the current thread is free. That happens before the second coroutineScope completes but after its lambda is finished. The current thread is suspended after println("in the coroutineScope 2")
, and only then the coroutine can start.
The second coroutine is launched before println("in the blocking")
, but it only starts executing when the current thread suspends, which is after the runBlocking
lambda finishes (but before runBlocking
itself returns).
For result B the first coroutine is launched between the two coroutineScopes, but as always it is only executed when the current thread suspends. That will be some time later, but first let's see what happens after the first coroutine is launched: The second coroutineScope is entered and the second coroutine is launched as well. We now have two scheduled coroutines waiting for execution.
The next window arrives when the second coroutineScope suspends after the execution of its lambda, right after println("in the coroutineScope 2")
but still before the coroutineScope itself returns. Now all scheduled coroutines are executed. We only have a single thread so this is done sequentially: The first coroutine first, and after it completes the second coroutine is executed.
Only when that also completes the control is given back to the second coroutineScope which determines that it is done (it needed to wait for the second coroutine to finish) and only then println("in the blocking")
is executed.
Upvotes: 0