Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
println
always prints 3 s regardless of whether I change the values of
delay
in the two doXX functions.
Both doXX functions take only 2 seconds, why is the result always 3
I think all three coroutines run concurrently, so I increased the delay in the last coroutine to wait for the first two to finish. Then I print the value of the variable
time
.
Here is the code.
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
launch { doSomethingUsefulOne() }
launch { doSomethingUsefulTwo() }
launch {
delay(6000)
println("Completed in $time ms")
suspend fun doSomethingUsefulOne() {
delay(1000L)
suspend fun doSomethingUsefulTwo(){
delay(1000L)
If I put them in a child scope of the runBlocking scope, the result is always correct. That is about 2 second.
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
doWorld
launch {
delay(4000)
println("Completed in $time ms")
suspend fun doWorld() = coroutineScope { // this: CoroutineScope
launch {
delay(2000L)
println("World 2")
launch {
delay(1000L)
println("World 1")
println("Hello")
Check the docs. The example at the top, which is very similar to yours should clarify this and maybe other aspects of coroutines.
The issue is that launch
launches a new coroutine and continues. The the block after measureTimeMillis
launches 2 coroutines and continues; this takes 3ms to run. The value 3 is stored in time
and that's what the 3rd coroutine prints.
–
–
You just discovered a feature of coroutines. They run in parallel. Let us look at the code:
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
launch { doSomethingUsefulOne() } // Launches first coroutine does NOT wait
launch { doSomethingUsefulTwo() } // Launches second coroutine does NOT wait
} // This block is finished in 3ms, because it only launches the coroutines
launch {
delay(6000)
println("Completed in $time ms")
If you want to wait for both of the coroutines to finish you can wrap them in coroutineScope
or runBlocking
:
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
runBlocking { // waits for all contained coroutines to finish
launch { doSomethingUsefulOne() } // Launches first coroutine does NOT wait
launch { doSomethingUsefulTwo() } // Launches second coroutine does NOT wait
launch {
delay(6000)
println("Completed in $time ms")
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.