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

13 | 什么是“协程思维模型”?

你好,我是朱涛。
学完基础篇以后,相信现在你对 Kotlin 的基础语法和特性都有了全面的认识。那么从今天开始,我们就要进入一个新的模块,一起来学习 Kotlin 当中最重要、最难学,也是最受期待的特性——协程。

为什么协程如此重要?

协程是 Kotlin 对比 Java 的最大优势,这也是我说协程是 Kotlin 中最重要特性的主要原因。虽说 Java 也在计划着实现自己的协程:Loom,不过这个毕竟还处于相当初级的阶段。而 Kotlin 的协程,可以帮我们极大地简化异步、并发编程、优化软件架构。通过协程,我们不仅可以提高开发效率,还能提高代码的可读性,由此也就可以降低代码出错的概率。
不过,遗憾的是,Kotlin 协程在业界的普及率并不高。因为,你如果对协程没有足够的认识,贸然在生产环境里使用协程,一定会遇到各种各样的问题,并要为之付出昂贵的代价(典型的反面例子就是滥用 GlobalScope,导致大量的计算资源浪费以及出现生命周期错乱的问题)。
Kotlin 的协程就是这样,表面上看,它的语法很简单,但行为模式却让人难以捉摸。举个简单的例子,同样是 5 行代码,普通的程序,这 5 行代码的运行顺序一般会是 1、2、3、4、5;但对于协程来说,代码执行顺序可能会是 1、4、5、3、2 这样错乱的。如果我们不能在脑子里建立协程的思维模型,那我们将很难理解协程的行为模式。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kotlin协程是一种备受期待的特性,它极大地简化了异步和并发编程,提高了软件架构的优化和开发效率。尽管学习协程可能具有一定难度,但建立协程思维模型对于解决问题提供了新的手段。协程的运行模式与普通程序有着明显的差异,它可以在任意yield的地方挂起并产出值,代表了“互相协作的程序”。理解了这一点后,读者可以快速将Kotlin协程的概念迁移至其他语言的协程中。除了介绍了协程的概念,文章还提到了Kotlin协程的两个概念:协程和协程框架。这些内容为读者提供了对Kotlin协程的全面了解,使其能够快速掌握该技术特性的核心概念和应用场景。 Kotlin协程框架作为一个独立的框架,与Kotlin的反射库类似,不直接集成在标准库中,而是需要手动进行依赖。这种设计减小了标准库的体积,给开发者更多的灵活性。协程的轻量特性使得它能够在一个线程中运行成千上万个协程,而且不会因为内存不足而异常退出。另外,协程并不会与特定的线程绑定,它可以在不同的线程之间灵活切换,为并发编程提供了更多的可能性。 文章通过比较线程和协程的不同,以及协程的轻量特性,帮助读者建立起对Kotlin协程的思维模型。这种思维模型将协程想象成一个更加轻量的线程,运行在线程中的轻量的Task,且能够在不同线程之间灵活切换。这样的总结能够帮助读者快速了解Kotlin协程的核心特点和优势,为进一步深入学习和应用提供了基础。

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

全部留言(36)

  • 最新
  • 精选
  • 曾帅
    之前看过另一位大佬 扔物线 说过的一个点,这里也想请教一下。就是运行在 JVM 上的 Kotlin 协程,本质上就是线程的封装,因为 JVM 上是没有协程这种东西。所以文章中说的一些概念,在 JVM 上运行的 Kotlin 来说,可能不适用。

    作者回复: 2019年的时候,我跟扔物线大佬同台做技术分享的时候,我们曾经在群里讨论过这个问题。“Kotlin协程在JVM上面是线程的封装”这没有错,这也是本质,谁都无法否认。 但是,这样的思维对我们学习Kotlin协程没有帮助,因为它过于底层,脱离了Kotlin的范畴。Java是不是二进制机器码的封装?当然是啦!但这个思路,能辅助我们学好Java的泛型吗?不能。 泛型是Java里才有的概念,机器码是感知不到的,因为“机器码”已经脱离了Java本身的范畴。同理,Kotlin协程是Kotlin才有的概念,JVM感知不到,因为它已经脱离了Kotlin的范畴。 换句话说,如果我们非要把Kotlin的协程类比成JVM的线程,我们就根本无法理解它的:“协作模式”、“非阻塞”、“挂起和恢复”、“结构化并发”、“冷数据流”、“异常处理机制”。 要知道,这都是Kotlin创造出来的概念啊,跟JVM一点关系都没有啊!所以,“Kotlin协程是JVM线程框架”这句话作为初步印象是可以的,但如果我们想要把Kotlin协程弄明白,还是要老老实实的去写Kotlin程序、读Kotlin的源码。

    2022-02-22
    5
    51
  • $Kotlin
    我已经在网上看了一周的协程资料了,在这里第一次看见这个抓手的思维模型,思路一下子就打开了,太强了。

    作者回复: 感谢认可,看到我的课程能真的帮到你,我也非常高兴。

    2022-02-11
    40
  • focus on
    请问文章中的动图是用什么软件制作的呢?

    作者回复: 我用PPT动画一帧帧做的。

    2022-02-11
    32
  • Paul Shan
    个人觉得把协程看做是封装的线程的看法帮助不大,线程是操作系统的概念,编程语言只是封装实现,让任务能够方便的被操作系统调度,调度是操作系统的事情,编程语言基本不管。协程是编程语言级别的任务,最终的调度可能是一个线程,也可能是共享的线程库,也可能是多个不同的线程,从线程角度很难理解协程的非阻塞,也无法理解协程之间的协同。我觉得把协程理解为编程语言级别的任务异步任务管理比较合适。虽然最终任务还是要给CPU执行,编译器(包括运行器)承担了大部分的分配调度责任。如果任务是CPU密集的,协程能提高的效率不多,毕竟CPU就这么多,操作系统的线程就是为这种场景设计的。如果任务是IO密集的,当年设计操作系统的时候,可没有想到会有那么多IO并发。协程比线程多出了线程内部异步的能力,让任务在CPU和IO之间不断调度轮转,可以充分利用CPU和IO设备,进而提高效率。Android程序和很多调用其他微服务的api都是IO很多的任务,协程能够提高效率。

    作者回复: 这个同学的解释也很透彻。

    2022-03-21
    26
  • 如浴春风
    「协程的“非阻塞”」那里,“阻塞”的概念可以可能会有同学存在跟我一样困扰。 其实可以这样理解: 如果在同一个 CoroutineContext 里调用了一个 suspend 方法,当前协程的顺序执行流会被“阻塞”,等待该 suspend 方法执行结束后回到原位置继续执行。但该协程所依赖的线程并不会被“阻塞”,有可能会被调度到执行其他协程任务。—— 这种的应用场景是,可以将各种回调通过封装,避免了回调地狱,同时使得代码逻辑更符合阅读习惯。 不得不说,作者的协程图示真形象!恳切建议其他同学一起细细揣摩下。

    作者回复: 感谢这位同学的补充,推荐其他同学也看看。

    2022-05-02
    11
  • ACE_Killer09
    repeat(3) { launch { repeat(3) { println(Thread.currentThread().name) delay(100) } } } repeat 是重复,launch是 创建协程。重复创建3个协程,每个协程执行3次,执行的内容是 打印协程执行时所在的线程。 结果说明同一个协程 可以再不同的线程上执行。

    作者回复: 感谢这位同学的补充,之前代码没看懂的同学可以看看。

    2022-02-11
    7
    8
  • _
    《深入理解JVM虚拟机》中提到过“协程”是“用户级线程”,不过这是从操作系统效率角度来称呼它,所以反而不太容易让“人”理解。而将“Kotlin协程”理解为“线程级Task”这种从上到下的角度要直观的多!大佬讲的很棒!👍🏻

    作者回复: 加油 :)

    2022-04-29
    5
  • Geek_0d808c
    在处理高并发,轻量任务的前提下,协程少了,线程创建的系统调用,上下文切换等时间,以及线程内存开销,是线程的复用,所以特定场景下,代价更小。

    作者回复: 说得很好!线程和协程,其实在特定场景下才有可比性。

    2022-02-11
    4
  • $Kotlin
    协程比乱用线程要高效,和合理使用线程池效率一致。

    作者回复: 嗯,没错。 PS:从你的留言时间,能看出是凌晨第一时间来看的更新,对吧?加油哈!一分耕耘一分收获,总有一天,量变会产生质变。

    2022-02-11
    3
  • 7Promise
    协程可以在适当的时机挂起和恢复,一个协程在挂起等待时,另外的协程也可以工作,比阻塞的线程更节省资源。

    作者回复: 嗯,不错的理解。

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