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

为何该Kotlin协程程序执行耗时10秒而非15秒?

Kotlin协程程序耗时与阻塞操作问题解答

1. 为什么总耗时是10秒而非15秒?

launch会启动一个独立的协程,它和runBlocking内部的主协程是并发执行的:

  • launch块里的逻辑:循环5次,每次延迟1秒后打印数字,整个过程共耗时5秒。
  • 主协程的逻辑:打印"Suspending....."后延迟10秒,最后输出"Finish"。

两个协程同时运行,总耗时由耗时更长的任务决定(也就是主协程的10秒),不是两者耗时相加。在主协程等待的10秒里,launch的协程早就完成了它的5秒任务,所以整体程序在10秒后结束。

2. 是否跳过了等待环节?

完全没有跳过等待:

  • launch协程里的5次delay(1000)都会完整执行,数字0到4会在程序启动后的第1到5秒依次打印出来。
  • 主协程的delay(10000)也会老老实实等够10秒,才会打印"Finish"。

两者只是借助协程的非阻塞挂起特性,在同一个线程上交替执行,不存在任何跳过等待的情况。

3. 换成真实耗时操作(比如数据库访问)会怎样?

这得看耗时操作是不是挂起函数:

  • 如果是挂起式耗时操作(比如用支持协程的数据库客户端,操作被封装成挂起函数):
    效果和delay一模一样,两个任务还是并发执行,总耗时依然由最长的任务决定(比如数据库操作总耗时5秒,主协程等10秒,整体就耗时10秒)。
  • 如果是阻塞式同步操作(比如直接调用普通JDBC接口,没做挂起包装,也没切换到Dispatcher.IO线程池):
    阻塞操作会占着当前线程(runBlocking默认用调用它的线程),主协程的delay必须等阻塞操作完成才能继续执行。这时候总耗时就变成两个任务的时间相加(比如数据库操作5秒 + 主协程等待10秒 = 15秒)。

要避免这种阻塞,建议把阻塞式操作放到withContext(Dispatchers.IO)里执行,这样任务会被放到专门的线程池,不会占用主协程的线程,就能恢复并发执行的特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:25:21