为何内联await同步执行,而Deferred的await却能并行执行?
为什么两段Kotlin协程代码的并发表现不同?
这和惰性启动无关——默认情况下async使用CoroutineStart.DEFAULT模式,会立即调度协程执行。两段代码的耗时差异,核心原因是协程的启动时机完全不同:
第一段代码(总耗时约1秒)
val d0 = async { delay1s() } val d1 = async { delay1s() } d0.await() d1.await()
执行流程:
- 连续调用两次
async,两个delay1s()协程会几乎同时被调度启动,各自开始执行delay(1000)。 - 调用
d0.await()时,当前协程挂起,等待约1秒后恢复;此时第二个协程的delay已经接近完成,d1.await()几乎不会等待,总耗时约1秒。
第二段代码(总耗时约2秒)
async { delay1s() }.await() async { delay1s() }.await()
执行流程:
- 第一行中,调用
async启动第一个协程后,立即调用await(),当前协程会挂起直到第一个协程的delay(1000)完全执行完毕(耗时1秒)。 - 只有第一个协程执行完成后,才会执行第二行的
async,此时第二个协程才开始启动并执行delay(1000),又耗时1秒,总耗时约2秒。
补充:关于惰性启动
如果显式指定async(start = CoroutineStart.LAZY),协程不会立即启动,只有在调用await()或start()时才会执行。这种情况下,第一段代码如果不提前启动协程,也会变成串行执行:
val d0 = async(start = CoroutineStart.LAZY) { delay1s() } val d1 = async(start = CoroutineStart.LAZY) { delay1s() } d0.await() // 此时才启动d0,执行1秒 d1.await() // 此时才启动d1,再执行1秒
但你示例中使用的是默认的立即启动模式,所以惰性启动不是导致差异的原因。
内容的提问来源于stack exchange,提问作者Tom Howard
相关产品推荐
相关产品推荐

