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

Kotlin协程异步代码运行为何需指定Dispatcher调度器?

Kotlin协程launch需指定调度器才并行的原因

核心逻辑一句话:协程的执行线程由调度器决定,单线程调度器只能串行,多线程调度器才能实现并行。

1. 未指定调度器时为啥是串行?

你应该是在runBlocking作用域里启动的协程——runBlocking默认使用绑定到当前调用线程的单线程调度器,所有在它内部启动且未指定调度器的协程,都会继承这个单线程上下文。

如果你的协程代码包含阻塞操作(比如Thread.sleep()),这个单线程会被第一个协程完全占用,第二个协程必须等第一个执行完毕才能启动,最终就会输出start A → finish A → start B → finish B的串行结果。哪怕用delay()这类挂起函数,如果代码是纯同步无挂起的逻辑,同样会串行执行。

对应你场景的代码示例:

runBlocking {
    // 继承runBlocking的单线程调度器
    launch {
        println("start A")
        Thread.sleep(1000) // 阻塞线程
        println("finish A")
    }
    launch {
        println("start B")
        Thread.sleep(1000)
        println("finish B")
    }
}

2. 指定Dispatchers.Default后为啥能并行?

Dispatchers.Default是Kotlin提供的多线程调度器,它背后是一个与CPU核心数匹配的共享线程池。

当你用launch(Dispatchers.Default)启动协程时,两个协程会被分配到线程池中的不同线程(或空闲线程)同时执行,阻塞操作各自占用不同线程,自然就能产生并行输出(比如start A → start B → finish A → finish B这类交错结果)。

对应代码示例:

runBlocking {
    launch(Dispatchers.Default) {
        println("start A")
        Thread.sleep(1000)
        println("finish A")
    }
    launch(Dispatchers.Default) {
        println("start B")
        Thread.sleep(1000)
        println("finish B")
    }
}

3. 额外补充

  • 协程本身不是线程,它的并行能力完全依赖调度器提供的多线程资源。
  • 除了Dispatchers.Default,Dispatchers.IO也是常用的多线程调度器,专门处理IO密集型任务;CPU密集型任务用Default更合适。
  • runBlocking的单线程默认调度器是故意设计的,目的是让其作用域内的代码在调用线程上顺序执行,避免不必要的线程切换复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:02:32