Kotlin 协程中的 Dispatchers

协程是 Kotlin 的核心异步能力,而 Dispatchers 则决定了协程在哪里、如何运行。

什么是 Dispatcher?

在 Kotlin 协程中,Dispatcher 决定了协程使用哪个线程或线程池执行。就像把任务分派到不同的"执行员"手里,不同的 Dispatcher 有不同的"专长"。

协程 = 轻量线程,而 Dispatcher = 线程调度器

常用的 Dispatchers 有:

  • Dispatchers.Default
  • Dispatchers.IO
  • Dispatchers.Main(仅限 Android 或支持 UI 的平台)

1. Dispatchers.Default

源码分析
Dispatchers.Default对应的实现位于DefaultScheduler

DefaultScheduler继承自SchedulerCoroutineDispatcher,并且传入参数:

  • corePoolSize = cpu核心数
  • MAX_POOL_SIZE = 2M
  • idleWorkerKeepAliveNs = 60s

从注释说明来看,当新的任务到来时,最大只有corePoolSize个Worker可以被创建

js 复制代码
* When a new task arrives in the scheduler (whether it is local or global queue),
* either an idle worker is being signalled, or a new worker is attempted to be created.
* (Only [corePoolSize] workers can be created for regular CPU tasks)

总结

  • 使用共享的后台线程池(基于 CPU 核心数)
  • 适合 CPU 密集型 操作(如排序、加密、JSON 解析等)
  • 线程数量默认是 Runtime.getRuntime().availableProcessors()

2. Dispatchers.IO

DefaultIoScheduler分发任务时,实际上使用了UnlimitedIoScheduler.limitedParallelism创建的CoroutineDispatcher,并且传入64

LimitedDispatcher.kt 最大会创建parallelism个worker用于执行任务

实际也是调用DefaultScheduler执行,不过传入的是BlockingContext,这个是跟Dispatchers.Default的区别所在,Dispatchers.Default是NonBlockingContext。

总结

  • 专为 IO 密集型 任务设计(文件、网络、数据库)
  • 使用可增长线程池(最多 64 个线程)
  • 会避免 Default 的线程被 IO 阻塞

错误使用 Dispatchers 的性能风险

示例:将 CPU 密集任务放到 Dispatchers.IO

js 复制代码
// 错误示例:将大量 CPU 计算任务放在 IO 线程池
launch(Dispatchers.IO) {
    repeat(100_000) {
        heavyComputation(it)
    }
}

1. IO 调度器并不为 CPU 密集任务设计

Dispatchers.IO 的线程池规模大(最大 64 线程),适合阻塞型任务(如文件、网络读取),而非频繁执行的 CPU 密集计算。

2. 上下文频繁切换(Context Switch)开销大 IO 调度器的线程数远高于 CPU 核心数,当你把密集计算放在里面时,操作系统将频繁在多个线程间切换 CPU 使用权,带来:

  • CPU cache 无法复用(尤其是 L1/L2 缓存失效)
  • 系统调度器负载增加
  • 实际执行速度反而变慢

3. 调度器饱和,真正的 I/O 请求被阻塞 计算任务长时间占用 IO 线程,导致后续的真正阻塞操作(如文件读取)排队,影响整个系统响应时间。

相关推荐
用户097 小时前
Kotlin Flow的6个必知高阶技巧
android·面试·kotlin
用户097 小时前
Jetpack Compose静态与动态CompositionLocal深度解析
android·面试·kotlin
Jeled19 小时前
「高级 Android 架构师成长路线」的第 1 阶段 —— 强化体系与架构思维(Clean Architecture 实战)
android·kotlin·android studio·1024程序员节
明道源码21 小时前
Kotlin 控制流、函数、Lambda、高阶函数
android·开发语言·kotlin
橙子1991101621 小时前
在 Kotlin 中,ViewModel 的获取
开发语言·vue.js·kotlin
hweiyu0021 小时前
Gradle 构建脚本迁移:从 Groovy DSL 到 Kotlin DSL,语法与技巧对比
开发语言·kotlin·gradle
消失的旧时光-194321 小时前
搞懂 Kotlin 的 List、Set、Map、HashMap、LinkedHashMap,以及 asSequence() 的底层原理与实战场景。
kotlin·数据处理·1024程序员节
明道源码21 小时前
Kotlin 面向对象编程、主构造函数、次构造函数、伴生对象、数据类、继承
kotlin·1024程序员节
消失的旧时光-19431 天前
Kotlin × Gson:为什么遍历 JsonObject 要用 entrySet()
android·kotlin·数据处理·1024程序员节
AH_HH2 天前
SmartCabinet:基于 Android 的智能储物柜管理系统技术解析
android·kotlin·存储柜