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

为何Kotlin协程添加delay(200ms)后仍先输出A再输出B?

Kotlin协程添加延迟后输出顺序疑问

以下两段代码运行在Kotlin Playground环境中:

代码片段1

fun main() {
  CoroutineScope(Dispatchers.IO).launch { 
        print("A")
    }
    print("B")
}

输出:AB

代码片段2

fun main() {
    CoroutineScope(Dispatchers.IO).launch { 
        delay(200)
        print("A")
    }
    print("B")
}

用户观察到输出仍为AB,疑惑为何添加200ms延迟后A仍先于B打印。


原因解释

首先得明确:标准JVM环境下的行为和你在Playground看到的完全不同:

  • 代码片段1:main函数的print("B")和协程的print("A")执行顺序完全不确定,可能输出AB也可能是BA;而且main执行完后JVM会直接退出,如果协程还没来得及执行,A根本不会被打印。
  • 代码片段2:main会先执行print("B"),随后JVM立刻退出,协程因为挂起且没有被等待,A根本不会执行。

你在Playground看到的现象,是平台特殊处理导致的:

  1. 强制等待协程完成:Playground为了让用户看到协程的执行结果,会在main函数结束后等待所有后台协程跑完才终止程序,所以哪怕协程里有delay(200),A最终还是会被打印。
  2. 偶发的输出顺序异常:你看到的AB顺序是极端偶发的线程调度巧合,或者输出缓冲的显示问题。正常情况下,这段代码在Playground里应该先输出B,等200ms后再输出A,最终显示BA。

为什么会出现这种偶发情况?因为线程调度没有绝对的先后顺序:

  • 调用launch后,协程被提交到Dispatchers.IO线程池,但delay(200)会让协程挂起、释放线程,进入等待状态。
  • 主线程此时本该立刻执行print("B"),但如果Playground的主线程因环境负载等原因被短暂阻塞,刚好协程在delay结束后先完成了print("A"),就会出现AB的输出顺序。但这不是常态,多运行几次大概率会看到BA。

最后提醒:实际开发中别用这种自定义的CoroutineScope,应该用runBlocking、viewModelScope这类带生命周期管理的作用域,避免协程泄漏或执行时机不可控的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:02:09