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 线程,导致后续的真正阻塞操作(如文件读取)排队,影响整个系统响应时间。

相关推荐
pengyu2 小时前
【Kotlin 协程修仙录 · 元婴境 · 中阶】 | 操作符真解:Flow 中间操作符与数据流变幻术
android·kotlin
pengyu3 小时前
【Kotlin 协程修仙录 · 元婴境 · 初阶】 | 冷流初啼:Flow 的基础与响应式编程的入门
android·kotlin
Kapaseker1 天前
破坏性更新 - 解读 Jetpack Compose 1.12
android·kotlin
Android-Flutter1 天前
android LeakCanary 工作原理 详解
android·kotlin
Android-Flutter1 天前
android 自定义view 详解
android·kotlin
Android打工仔1 天前
从 finally 理解程序的控制流:它为什么不是 catch 后面的代码?
android·kotlin
YXL1111YXL1 天前
续体和状态机 —— suspend 函数的 CPS 变换
android·kotlin
alexhilton1 天前
千万别误用Android Skills
android·kotlin·android jetpack
必须会一定会1 天前
GLM-5.3 迁移实战:强制思考、1M 上下文与官方编程基准
android·开发语言·kotlin
阿pin2 天前
Android随笔-kotlin withContext
android·kotlin·withcontext