You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin协程中awaitAll()的行为差异及串行执行原因探究

协程作用域位置对执行效率的影响

预热后执行两个函数的结果差异明显:

  • good():7ms
  • bad():618ms

核心原因解析

要理解这个差异,关键在于coroutineScope的特性:它是一个挂起函数,会等待其内部所有子协程执行完毕后,自身才会结束挂起。

good()的并行执行逻辑

在good()中,repeat(100)循环被包裹在同一个coroutineScope内部:

  • 循环的100次迭代中,每次调用async都会在这个共享的作用域下启动一个子协程
  • 这些子协程会被调度器并行执行,各自的delay(5)不会互相阻塞
  • coroutineScope会等待这100个协程全部完成,总耗时只接近单个delay(5)的时间(加上少量调度开销,因此是7ms左右)

bad()的串行执行逻辑

在bad()中,repeat(100)循环在coroutineScope外部,每次迭代都会创建一个新的coroutineScope:

  • 第一次循环创建的coroutineScope内部启动一个async协程,coroutineScope必须等这个协程的delay(5)执行完才会结束
  • 只有当前一个coroutineScope结束后,才会进入下一次循环,创建新的作用域和协程
  • 相当于100个协程依次串行执行,总耗时是5ms * 100加上调度开销,最终达到618ms左右

完整代码

suspend fun good() =
    buildList {
        coroutineScope {
            // 在coroutineScope内部循环
            repeat(100) {
                add(async { delay(5) })
            }
        }
    }.awaitAll()

suspend fun bad() =
    buildList {
        // 在coroutineScope外部循环
        repeat(100) {
            coroutineScope {
                add(async { delay(5) })
            }
        }
    }.awaitAll()

suspend fun main() {
    // 预热操作
    measureTimeMillis { good() }
        .also { println("good: ${it}ms") }
    measureTimeMillis { bad() }
        .also { println("bad: ${it}ms") }
}

内容的提问来源于stack exchange,提问作者JasonMing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:45:56