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

28 | launch的背后到底发生了什么?

你好,我是朱涛。
在前面的课程里,我们一直在研究如何使用 Kotlin 协程,比如,如何启动协程,如何使用挂起函数,如何使用 Channel、Flow 等 API。但到目前为止,我们只知道该怎么用协程,对它内部的运行机制并没有深究。
现在我们都知道,launch、async 可以创建、启动新的协程,但我们只能通过调试参数,通过 log 看到协程。比如我们可以回过头来看下第 13 讲当中的代码:
// 代码段1
// 代码中一共启动了两个协程
fun main() = runBlocking {
println(Thread.currentThread().name)
launch {
println(Thread.currentThread().name)
delay(100L)
}
Thread.sleep(1000L)
}
/*
输出结果:
main @coroutine#1
main @coroutine#2
*/
现在回过头来看,这段代码无疑是非常简单的,runBlocking{} 启动了第一个协程,launch{} 启动了第二个协程。可是,有一个问题,我们一直都没有找到答案:协程到底是如何创建的?它对应的源代码,到底在哪个类?具体在哪一行?
我们常说 Java 线程的源代码是 Thread.java,这样说虽然不一定准确,但我们起码能看到几个暴露出来的方法。那么,在 Kotlin 协程当中,有没有类似 Coroutine.kt 的类呢?对于这些问题,我们唯有去阅读 Kotlin 协程的源码、去分析 launch 的启动流程,才能找到答案。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kotlin协程是一种强大的并发编程工具,本文深入探讨了launch和async创建、启动新协程的内部运行机制,揭示了协程的基础元素和内部机制。通过分析createCoroutine{}和startCoroutine{}函数,揭示了协程的执行流程。文章还通过反编译代码展示了startCoroutine()方法的实现原理,深入剖析了协程的执行流程。通过对createCoroutine()和startCoroutine()的源码分析,读者可以更加透彻地了解Kotlin协程的内部运行机制。文章对于想要深入了解Kotlin协程的读者来说,是一篇极具价值的技术文章。 在文章中,通过分析launch{}的源代码,揭示了其内部启动协程的过程。通过反编译和源码分析,展示了startCoroutine()方法的实现原理,以及对应的Java代码。文章还推导了startCoroutineCancellable()方法的调用过程,深入剖析了launch启动协程的整个过程。此外,文章还提到了createCoroutine{}和startCoroutine{}是Kotlin提供的两个底层API,以及Kotlin协程框架在中间层实现了launch、async之类的协程构建器,对协程底层API进行了更好的封装。 总的来说,本文通过深入分析Kotlin协程的内部运行机制和源码实现,为读者提供了深入了解Kotlin协程的机会,对于想要深入学习该技术的读者具有重要的参考价值。

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

全部留言(14)

  • 最新
  • 精选
  • 辉哥
    startCoroutine -> createCoroutineUnintercepted -> createCoroutineFromSuspendFunction,最终返回一个RestrictedContinuationImpl对象,然后调用其resume方法,从而调用block的invoke方法.最终调起协程.

    作者回复: 很棒的解答!

    2022-03-29
    5
  • 杨小妞
    createCoroutineUnintercepted这个函数的JVM实现在哪个包,哪个类下呢?

    作者回复: 去Kotlin源码中,找一下这个类:IntrinsicsJvm.kt

    2022-04-06
    1
  • Paul Shan
    思考题:调试了一下,结果是一样的。唯一的区别可能在于block原来被反编译成一个函数对象直接用实现状态机的Continuation对象赋值。加入函数赋值以后,block对象被实现为一个简单的内部类,这个内部类的invoke函数再去调用Continuation对象。

    作者回复: 是的。

    2022-03-28
    1
  • ACE_Killer09
    代码段16中, 我理解resume 之后 会回到 LaunchUnderTheHoodKt$testLaunch$1 # invoke ,再进一步到invokeSuspend 进入状态机的流程。那么 Continuation#resume -> invoke这个过程是怎么调用过来的?

    作者回复: 你可以去看看BaseContinuationImpl#resumeWith(),具体逻辑在那里。

    2022-04-16
  • L先生
    反编译了一下,block最终会转成function1。(this as Function1, Any?>).invoke(it)中的invoke是指的这个Function1中的invoke吗

    作者回复: 接近了~~

    2022-03-28
  • L先生
    打印没啥区别啊。应该是走这里了。createCoroutineFromSuspendFunction(probeCompletion) { (this as Function1, Any?>).invoke(it) }。但是我看不太懂。this指什么,it又指什么参数

    作者回复: 嗯,方向已经对了。

    2022-03-28
    2
  • Allen
    关于思考题的思考: 我认为执行流程及结果和代码段 3 中是完全一样的。因为 private suspend fun func(): String { println("Hello!") delay(1000L) println("World!") return "Result" } 和 val block = suspend { println("Hello!") delay(1000L) println("World!") "Result" } 完全是等价的写法。

    作者回复: 写法是等价的,那么执行流程有变化吗?

    2022-03-28
  • 郑峰
    深层认识: suspend function type 底层被实现为Continuation。所以协程启动就是Continuation的resume。协程的启动实际上是Continuation的一个应用。
    2022-08-23归属地:美国
    1
  • Temme
    ”注释 2 处的 (this is BaseContinuationImpl) 条件一定是为 true 的“ 这句话好像是错的SuspendLambda并不是BaseContinuationImpl的子类
    2024-02-16归属地:上海
    1
  • anmi
    完了,现在编译后没有block这个类
    2024-01-15归属地:江苏
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部