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

30 | CoroutineScope是如何管理协程的?

你好,我是朱涛。
通过前面课程的学习,我们知道 CoroutineScope 是实现协程结构化并发的关键。使用 CoroutineScope,我们可以批量管理同一个作用域下面所有的协程。那么,今天这节课,我们就来研究一下 CoroutineScope 是如何管理协程的。

CoroutineScope VS 结构化并发

在前面的课程中,我们学习过 CoroutineScope 的用法。由于 launch、async 被定义成了 CoroutineScope 的扩展函数,这就意味着:在调用 launch 之前,我们必须先获取 CoroutineScope。
// 代码段1
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {}
public fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T> {}
private fun testScope() {
val scope = CoroutineScope(Job())
scope.launch{
// 省略
}
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入解释了CoroutineScope如何管理协程的重要性和工作原理。通过对比早期协程API和现在的CoroutineScope,阐述了结构化并发的重要性。文章通过源码分析CoroutineScope是如何通过Job来管理协程的,以及协程的父子关系是如何建立的。此外,文章还指出了父协程如何取消子协程,将协程的结构比喻为一颗N叉树,每个协程对应一个Job对象,父协程可以有多个子协程。通过深入浅出的方式,为读者提供了清晰的技术概览。文章还提到了协程的“结构化取消”部分的逻辑,以及协程的取消事件以及异常传播的传递规律。最后,文章提出了一个思考题,引导读者通过学习的知识点来分析SupervisorJob的原理。整体来看,本文通过源码分析深入浅出地解释了CoroutineScope是如何管理协程的,为读者提供了清晰的技术概览。

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

全部留言(6)

  • 最新
  • 精选
  • Paul Shan
    思考题:SupervisorJob 重写了childCancelled方法,当异常发生,错误在整个树中传递,调用到​​cancelParent会调用parent.childCancelled,这个时候就会直接返回false而不是调用cancelImpl,错误传递就会终止,父协程不会被cancle掉。执行的路径其实和CancellationException异常类似,区别是cancelParent的返回值。

    作者回复: 是的

    2022-04-01
    10
  • 飓风
    CancellationException 引起的异常,会传递给兄弟节点吗?

    作者回复: 传递给兄弟节点的前提是要通过父节点,所以当然是不能的。

    2022-04-13
    6
  • 辉哥
    原文: 另外,由于 CoroutineScope 当中的 Job 是我们手动创建的,并不需要执行任何协程代码,所以,它会是 true。也就是说,这里会执行注释 2 对应的代码 涛哥,结合上下文的意思,这里应该是会执行注释1对应的代码吧

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

    2022-04-02
    1
  • 杨小妞
    环境:implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0' 问题1:“而代码段 5 当中的 CoroutineScope(Job()),改成 CoroutineScope() 也是完全没问题的”,这里参数是不能为空的吧? 问题2:在创建CoroutineScope的时候,即使外部不传入Job,内部也会自己创建一个Job,那么JobSupport.initParentJob判断parent == null是否就多余了? 问题3:SupervisorJob可以阻断异常传递给父协程,它自己本身的子协程也是能接收到异常的吧。

    作者回复: 问题1:你说的对,这里用CoroutineScope(EmptyCoroutineContext)更准确。 问题2:创建CoroutineScope的方式有很多,这里只能保证CoroutineScope()创建的一定有Job,所以initParentJob当中的判断仍然是有用的。 问题3:可以的。

    2022-04-13
    2
  • anmi
    代码段4,假设launch是普通顶层函数,那么job应该取消不了里面的两个子协程吧了?
    2023-12-21归属地:江苏
  • 无咎
    既然协程是结构化,有方法类似于tree命令,来dump协程的树形结构吗?
    2022-06-24
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部