科特林等待不暂停?

Kotlin await not suspending?

我在 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")
    }
}

输出为

1st
2nd
2nd end
1st end
end

我的理解是,await()是一个挂起函数,意思是"paused"在那里执行。所以我想,实际上首先 async1 会被执行,然后 async2 会被执行。所以我希望输出是

1st
1st end
2nd
2nd end    
end

显然发生的是,async1async2 并行执行,这可以看作是 async1 的输出夹在 [=15 的输出之间=].

所以我现在的具体问题是:为什么 Kotlin 没有在 async1 暂停,而是同时启动 async2

await() 将挂起它 运行 中的协程 - 这是你的主块(线程 runBlocking() 是 运行ning,因为它正在阻塞),所以 async2.await() 不会被调用,除非 async1 完成。 但是由于 async() 函数的执行是立即开始的,默认情况下会在后台线程池中执行,所以不会被阻塞。 你可以通过添加

来检查它
 async1.await()
 println("between")
 async2.await()

并且看到,"between" 将始终在“1st end”之后打印

如果您希望协程按顺序 运行 - 使用 runBlocking() 生成器(或者在大多数情况下,对于这种情况根本不需要使用协程)

async/await 的想法是 运行 并行任务,并且在等待其中一项任务的结果时不要阻塞其他任务。

Why did Kotlin not suspend on async1, but concurrently started async2?

async 在后台生成一个新任务。任务立即开始执行。您无法控制它的暂停,并且有整个 class 的用例它永远不会被暂停。我们经常使用async将阻塞任务提交到线程池。

await 暂停当前协程,直到任务完成并产生结果。它对任务的执行没有影响。即使您从未调用 await.

,该任务也会 运行 完成

如果您特别希望仅在调用 await 时触发任务,您可以指定 start = LAZY:

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

    async1.await()
    async2.await()

    println("end")
}

这会按照您预期的顺序可靠地打印。