朱涛 · Kotlin 编程第一课
朱涛
Google 认证的 Kotlin、Android 开发者专家,博客“Kotlin Jetpack 实战”作者
6717 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
朱涛 · Kotlin 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

29 | Dispatchers是如何工作的?

你好,我是朱涛。今天,我们来分析 Kotlin 协程当中的 Dispatchers。
上节课里,我们分析了 launch 的源代码,从中我们知道,Kotlin 的 launch 会调用 startCoroutineCancellable(),接着又会调用 createCoroutineUnintercepted(),最终会调用编译器帮我们生成 SuspendLambda 实现类当中的 create() 方法。这样,协程就创建出来了。不过,协程是创建出来了,可它是如何运行的呢?
另外我们也都知道,协程无法脱离线程运行,Kotlin 当中所有的协程,最终都是运行在线程之上的。那么,协程创建出来以后,它又是如何跟线程产生关联的?这节课,我们将进一步分析 launch 的启动流程,去发掘上节课我们忽略掉的代码分支。
我相信,经过这节课的学习,你会对协程与线程之间的关系有一个更加透彻的认识。

Dispatchers

在上节课里我们学习过,launch{}本质上是调用了 startCoroutineCancellable() 当中的 createCoroutineUnintercepted() 方法创建了协程。
// 代码段1
public fun <T> (suspend () -> T).startCoroutineCancellable(completion: Continuation<T>): Unit = runSafely(completion) {
// 注意这里
// ↓
createCoroutineUnintercepted(completion).intercepted().resumeCancellableWith(Result.success(Unit))
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入分析了Kotlin协程中Dispatchers的工作原理,重点围绕着launch的Dispatchers执行流程展开。文章首先介绍了Dispatchers、CoroutineDispatcher、ContinuationInterceptor、CoroutineContext之间的关系,以及它们的继承关系。通过分析launch的源代码,解释了协程默认运行在Dispatchers.Default线程池上的原因。此外,文章还详细讲解了newCoroutineContext()方法的逻辑,以及在没有指定Dispatcher时,协程会默认使用Dispatchers.Default线程池。最后,文章提到了接下来将分析intercepted()的逻辑。通过本文的学习,读者可以更加深入地了解协程与线程之间的关系,以及Kotlin协程中Dispatchers的工作原理。文章内容涉及技术性较强,对于想要深入了解协程本质的读者具有重要参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • Paul Shan
    Kotlin在开启协程状态机之前做了大量的工作,从父协程那里继承了状态,重新设定了子协程运行线程,检查了各种异常情况,区分了程序异常和协程cancel的情况,最终在指定的线程里启动了状态机。协程的重点不在线程,而在线程之外的调度,异常处理和状态机。

    作者回复: “协程的重点不在线程,而在线程之外的调度,异常处理和状态机。”这句话总结很到位。

    2022-03-30
    8
  • Allen
    协程本质上是对线程的封装,我们在使用协程的时候,并不需要直接与线程打交道,直接使用 Coroutine 提供的相关 API 以同步的方式就可以间接完成与线程之间的交互。

    作者回复: 是的。

    2022-03-31
    4
  • 7Promise
    kotlin的协程与java线程密不可分,协程最终是运行在线程中的Task。

    作者回复: 是的~

    2022-03-30
    4
  • 神佑小鹿
    如果挂起后,再恢复,是如何恢复到之前的线程的呢?? 这个线程的是如何保存的呢??

    作者回复: 这个问题三言两语很难解释清楚了,给你个方向吧,你可以这样去做: 写一个简单的Demo,然后用课程当中的方法,去研究协程恢复之后的代码执行流程。其实,协程的基本元素理解透彻以后,协程的源码读起来就不是那么费力了。

    2022-04-16
    2
  • Allen
    这里,请你留意代码中我标记出的注释,intercepted() 方法首先会判断它的成员变量 intercepted 是否为空,如果不为空,就会调用 context[ContinuationInterceptor],获取上下文当中的 Dispatcher 对象。以代码段 3 当中的逻辑为例,这时候的 Dispatcher 肯定是 Default 线程池。 涛哥,这里应该是 intercepted 为空才会调用 context[ContinuationInterceptor] 吧?

    作者回复: 是的,笔误了,感谢指出来了。

    2022-03-30
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部