Search code examples
kotlinkotlinx.coroutines

Kotlin await not suspending?


i have the following code in Kotlin

import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>) {

    runBlocking {
        val async1 = async {
            println("1st")
            delay(2000)
            println("1st end")
        }
        val async2 = async {
            println("2nd")
            delay(1000)
            println("2nd end")
        }

        async1.await()
        async2.await()

        println("end")
    }
}

The output is

1st
2nd
2nd end
1st end
end

My understanding was, that await() is a suspending function, meaning the execution is "paused" there. So i thought, that actually first async1 would be executed, and THEN async2 would be executed. So i expected the output to be

1st
1st end
2nd
2nd end    
end

What obviously happened was, that both async1 and async2 where executed in parallel, which can be seen as the output of async1 is sandwiched between the outputs of async2.

So my concrete question is now: Why did Kotlin not suspend on async1, but concurrently started async2?


Solution

  • await() will suspend coroutine it run's in - which is your main block (and a thread runBlocking() is running, because it's blocking), so async2.await() will not be called, unless async1 is finished. But since execution of async() function is started immediately and will be executed by default on background thread pool, it will not be blocked. You can check it by adding

     async1.await()
     println("between")
     async2.await()
    

    and see, that "between" will always be printed after "1st end"

    If you want coroutines to run sequentially - use runBlocking() builder (or in most cases no need to use coroutines at all for such cases)

    The idea of async/await is to run tasks in parallel and don't block other tasks while you waiting for results of one of them.