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

Kotlin协程runBlocking是否无论何种场景都会阻塞主线程?

关于runBlocking是否总会阻塞主线程的疑问与解答

疑问背景

  • runBlocking官方文档说明:

    启动新协程并阻塞当前线程直至协程完成。该函数不应在协程内部使用,用于衔接常规阻塞代码与挂起风格的库,适用于主函数及测试场景。
    据此我认为runBlocking仅阻塞当前线程。

  • 《Kotlin Coroutines Deep Dive》一书中提到:

    "借助调度器,我们可以让runBlocking在不同线程运行,但启动该构建器的线程仍会被阻塞直至协程完成。"
    我曾误解为即便通过withContext等方式切换至工作线程并在其中运行runBlocking,它仍会阻塞包括主线程在内的所有线程,因此想确认:无论采用何种方式,runBlocking是否总会阻塞主线程?

解答

runBlocking 只会阻塞调用它的那个线程,并非总会阻塞主线程,核心逻辑如下:

  • 如果在主线程中调用runBlocking,那么主线程会被阻塞,直到内部协程执行完毕;
  • 如果在子线程中调用runBlocking,那么只有调用它的这个子线程会被阻塞,主线程可以正常执行其他任务,完全不受影响;
  • 书中所说的“借助调度器让runBlocking在不同线程运行”,指的是runBlocking内部的协程代码可以通过指定调度器(比如Dispatchers.IO)在其他线程上执行,但调用runBlocking的原始线程仍然会被挂起等待,直到内部所有协程任务完成,这和“阻塞所有线程”完全是两回事。

举个简单示例:

fun main() {
    // 在主线程启动子线程
    Thread {
        // 在子线程中调用runBlocking
        runBlocking(Dispatchers.IO) {
            delay(3000)
            println("runBlocking内部任务完成")
        }
        println("子线程执行完毕")
    }.start()

    // 主线程继续执行,不会被阻塞
    println("主线程正在执行其他任务")
    Thread.sleep(4000)
    println("主线程执行完毕")
}

这段代码中,runBlocking在子线程中调用,主线程不会被阻塞,会正常输出"主线程正在执行其他任务",等待3秒后子线程的runBlocking任务完成,最后主线程完成自己的延迟任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:35:15