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

在协程中使用runBlocking是否会引发问题?官方文档为何禁止?

这是个非常典型的协程入门坑,很多刚接触Kotlin协程的开发者都可能不小心踩进去,咱们一步步把这个问题说清楚:

在协程中使用runBlocking的风险与官方解释

为什么官方明确禁止在协程中调用runBlocking?

首先直接看官方文档的明确声明:

"This function should not be used from a coroutine"

要理解这句话,得先搞懂runBlocking的本质:它是专门用来打通阻塞式代码和协程代码的桥梁。它的设计初衷是在非协程环境(比如普通的main函数、传统的阻塞式线程任务)里启动协程,并且阻塞当前线程,直到内部的协程逻辑全部执行完毕。

而如果你已经在一个协程里面了,意味着你已经处于支持挂起的上下文环境中——协程的核心优势就是用非阻塞的挂起来替代线程阻塞,这时候再调用runBlocking,相当于放弃了协程的非阻塞特性,强行把当前线程卡住,完全违背了协程的设计理念,所以官方说这种用法“毫无意义”:你本来可以用launch、async直接启动子协程,或者直接调用挂起函数,根本没必要多此一举去阻塞线程。

嵌套runBlocking的简单场景表现

就像你写的这段测试代码:

fun main(args: Array<String>) { 
    runBlocking { 
        runBlocking { 
            println("hi") 
        } 
    }
}

它确实能编译运行,因为语法上没有错误,但IntelliJ会弹出警告——这是IDE在提醒你:你正在做不符合协程最佳实践的操作。

这段代码的执行逻辑其实是冗余的:

  1. 外层runBlocking启动协程,同时阻塞main线程;
  2. 内层runBlocking又启动一个协程,再次阻塞当前的main线程(因为外层协程运行在main线程上);
  3. 内层协程打印完成后,内层runBlocking释放线程;
  4. 外层协程完成,外层runBlocking释放main线程。

说白了就是做了两次没必要的线程阻塞,纯粹是多余操作。

复杂场景下的致命风险:死锁与性能损耗

如果是在更复杂的业务场景里,比如使用了限定线程数量的Dispatcher(比如Dispatchers.IO、自定义的单线程Dispatcher),嵌套runBlocking很容易引发死锁。举个典型的例子:

fun main() = runBlocking(Dispatchers.IO) {
    println("外层协程运行在:${Thread.currentThread().name}")
    runBlocking(Dispatchers.IO) {
        println("内层协程运行在:${Thread.currentThread().name}")
    }
}

这段代码大概率会触发死锁:

  • 外层runBlocking占用了Dispatchers.IO线程池中的一个线程;
  • 内层runBlocking试图在Dispatchers.IO上启动协程,但如果此时IO线程池的所有线程都被占用(比如刚好达到最大并发数,或者你用的是单线程Dispatcher),它会一直等待线程可用;
  • 但外层的线程被内层runBlocking死死阻塞着,永远不会释放——死锁就这样发生了,程序会卡在那里一动不动。

除此之外,这种用法还会带来性能损耗:线程是宝贵的系统资源,runBlocking会持续占用线程直到内部协程完成,过度阻塞会导致线程池耗尽,直接降低整个应用的并发处理能力。

总结

  • 从设计初衷来看,runBlocking是“从阻塞世界进入协程世界”的入口,在协程内部调用它完全违背设计逻辑,毫无意义;
  • 简单测试场景下可能不会崩溃,但会做冗余的线程阻塞;
  • 复杂业务场景(尤其是使用限定Dispatcher时)极易引发死锁,还会拖垮应用性能;
  • 永远遵循官方建议:不要在协程中调用runBlocking,如果需要在协程内启动子任务,用launch、async或者直接调用挂起函数就好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:56