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

CoroutineScope与runBlocking行为差异:两种launch输出不同的原因

差异原因解析

1. 直接使用launch的场景

直接在runBlocking代码块内调用launch,该协程属于runBlocking自身创建的作用域。

runBlocking的核心特性是:会阻塞当前线程(此处为主线程),直到其作用域内的所有子协程全部执行完成才会返回。你的代码中,awaitAll().sum()执行完毕后,runBlocking并不会立刻返回结果,而是会等待自己作用域内那个delay(5000)的协程执行完毕,因此该协程能走完整个流程,打印出"I am late"和finally块中的"I am finalled"。

2. 使用scope.launch的场景

这里的scope是外部传入的CoroutineScope(Dispatchers.IO),通过它启动的协程属于这个外部作用域,和runBlocking的作用域完全独立。

  • 首先,CoroutineScope本身不会自动取消:你创建的CoroutineScope(Dispatchers.IO)没有绑定任何生命周期,也没有手动调用cancel(),所以当testFun1执行完毕后,这个作用域不会主动取消内部协程。
  • 其次,进程终止导致协程中断:如果这段代码在主线程中执行,当compParallel返回结果、testFun1打印完output后,主线程执行完毕,JVM进程直接终止。此时那个delay(5000)的协程还在等待,还没到打印时机就被强制终止,自然不会输出任何内容。

你之前的误解在于认为CoroutineScope对象被销毁时会自动取消协程,但实际上CoroutineScope只是协程上下文的持有者,它的销毁不会触发协程取消,必须手动调用scope.cancel()才能让内部协程进入取消流程,触发finally块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:30:01