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

runBlocking启动的协程能否多线程执行?是否保证线程一致?

关于runBlocking协程恢复线程的问题

结论:不一定会在启动时的t1线程恢复,完全有可能切换到Dispatcher.Default线程池里的其他线程(比如你猜测的DefaultDispatcher-worker-2)。

具体原因:

  • 当你使用runBlocking(Dispatchers.Default)时,协程运行在Default调度器的线程池上,这个线程池的默认线程数和CPU核心数一致(比如4核设备就是4个线程)。
  • delay()是一个非阻塞的挂起函数,它会让当前协程释放占用的线程(t1),这个线程会回到线程池供其他任务复用。
  • 当delay结束后,协程需要恢复执行,此时会从Default线程池里选取空闲的线程继续执行后续代码,这个线程可能是原来的t1,也可能是线程池里的其他线程。

为什么你每次都得到同一个线程?

这只是巧合——你的代码逻辑简单,没有其他并发任务抢占线程池资源。当delay结束时,原来的t1线程刚好处于空闲状态,所以协程直接复用了它。如果在delay期间,线程池里的其他线程被其他任务占用,恢复时就很可能切换到其他线程。

验证线程切换的方法

你可以在delay期间添加一些并发任务,占用线程池的其他线程,就能看到线程切换的现象:

fun main(): Unit = runBlocking(Dispatchers.Default) {
    println("runBlocking start: ${Thread.currentThread().name}")

    // 启动多个协程占用线程池资源
    repeat(4) {
        launch {
            delay(2000)
            println("Child coroutine on: ${Thread.currentThread().name}")
        }
    }

    delay(3000)

    println("runBlocking end: ${Thread.currentThread().name}")
}

运行这段代码,大概率会看到end的线程和start的线程不一样。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:22:03