Kotlin 协程的模型可以理解为“结构化并发”(Structured Concurrency)。这不仅仅是一个编程技巧,而是一套完整的设计哲学,它规定了协程如何启动、如何调度、如何管理生命周期以及如何传递异常。
-
本质模型:用户态的轻量级线程
协程并不是操作系统线程,而是运行在线程之上的“用户态线程”。
轻量级:一个线程的栈内存通常需要 1MB,而一个协程仅需约 1KB。这意味着你可以在有限的内存中轻松创建数十万个协程。
挂起不阻塞 (Suspend without Blocking):这是协程最核心的特性。当协程遇到耗时操作(如 delay 或网络请求)时,它会挂起(暂停执行并保存状态),同时释放底层的操作系统线程去处理其他任务。待耗时操作完成后,再恢复执行。 -
结构模型:树状的 Job 层级
在 Kotlin 中,协程不是孤立存在的,它们通过 Job 形成严格的父子树状结构。
父管子:当你启动一个协程(子)时,它会自动成为当前作用域(父)的孩子。
级联取消:如果父协程被取消(例如页面销毁),它会自动递归取消所有的子协程。这从根本上解决了“孤儿协程”导致的内存泄漏问题。
等待完成:父协程必须等待所有子协程完成后,自己才算完成。 -
异常模型:同生共死与向上传播
默认的协程模型遵循“同生共死”的原则(除非使用 SupervisorJob)。
异常向上传播:如果一个子协程抛出未捕获的异常,这个异常会沿着树向 上传递给父协程,导致父协程及其所有兄弟协程都被取消。
设计意图:这是一种安全策略,防止程序在部分失败的状态下继续运行, 造成数据不一致。 -
调度模型:Dispatcher 决定在哪里跑
协程本身不绑定特定线程,而是由 CoroutineDispatcher 来决定它在哪个线 程池中运行。Kotlin 提供了三种标准调度器:
| 调度器 | 适用场景 | 底层实现 |
|---|---|---|
| Dispatchers.Main | UI 更新、快速操作 | Android 主线程 |
| Dispatchers.IO | 网络请求、读写文件/数据库 | 动态调整的大型线程池 (默认最大64核) |
| Dispatchers.Default | CPU 密集型计算 (排序、JSON解析) | 等于 CPU 核心数的固定线程池 |
- 数据流模型:Flow 响应式管道
对于异步数据流(不仅仅是单个结果),Kotlin 提供了 Flow 模型,它与协程天然契合。
冷流 (Cold Stream):只有当有收集者 (collect) 时,Flow 才会开始执行。
背压支持:Flow 能够自动处理生产者和消费者速度不匹配的问题,防止内存溢出。
StateFlow & SharedFlow:这是 Flow 的特化版本,分别用于替代 LiveData 进行状态管理和事件广播
| 概念 | 形象理解 | 关键点 |
|---|---|---|
| CoroutineScope | 容器/管家 | 决定了协程的生命周期边界(如页面销毁即停止)source_group_web_6。 |
| Job | 句柄/遥控器 | 用来控制协程(取消、等待),并维护父子关系source_group_web_7。 |
| suspend | 暂停键 | 允许函数暂停而不阻塞线程,必须在协程上下文中调用source_group_web_8。 |
| Dispatcher | 调度员 | 告诉协程该去哪个线程干活source_group_web_9。 |
| Continuation | 备忘录 | 编译器生成的对象,记录了“暂停后下一步该做什么”source_group_web_10。 |

412

被折叠的 条评论
为什么被折叠?



