13 | 什么是“协程思维模型”?
为什么协程如此重要?
- 深入了解
- 翻译
- 解释
- 总结
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-22551 - $Kotlin我已经在网上看了一周的协程资料了,在这里第一次看见这个抓手的思维模型,思路一下子就打开了,太强了。
作者回复: 感谢认可,看到我的课程能真的帮到你,我也非常高兴。
2022-02-1140 - focus on请问文章中的动图是用什么软件制作的呢?
作者回复: 我用PPT动画一帧帧做的。
2022-02-1132 - Paul Shan个人觉得把协程看做是封装的线程的看法帮助不大,线程是操作系统的概念,编程语言只是封装实现,让任务能够方便的被操作系统调度,调度是操作系统的事情,编程语言基本不管。协程是编程语言级别的任务,最终的调度可能是一个线程,也可能是共享的线程库,也可能是多个不同的线程,从线程角度很难理解协程的非阻塞,也无法理解协程之间的协同。我觉得把协程理解为编程语言级别的任务异步任务管理比较合适。虽然最终任务还是要给CPU执行,编译器(包括运行器)承担了大部分的分配调度责任。如果任务是CPU密集的,协程能提高的效率不多,毕竟CPU就这么多,操作系统的线程就是为这种场景设计的。如果任务是IO密集的,当年设计操作系统的时候,可没有想到会有那么多IO并发。协程比线程多出了线程内部异步的能力,让任务在CPU和IO之间不断调度轮转,可以充分利用CPU和IO设备,进而提高效率。Android程序和很多调用其他微服务的api都是IO很多的任务,协程能够提高效率。
作者回复: 这个同学的解释也很透彻。
2022-03-2126 - 如浴春风「协程的“非阻塞”」那里,“阻塞”的概念可以可能会有同学存在跟我一样困扰。 其实可以这样理解: 如果在同一个 CoroutineContext 里调用了一个 suspend 方法,当前协程的顺序执行流会被“阻塞”,等待该 suspend 方法执行结束后回到原位置继续执行。但该协程所依赖的线程并不会被“阻塞”,有可能会被调度到执行其他协程任务。—— 这种的应用场景是,可以将各种回调通过封装,避免了回调地狱,同时使得代码逻辑更符合阅读习惯。 不得不说,作者的协程图示真形象!恳切建议其他同学一起细细揣摩下。
作者回复: 感谢这位同学的补充,推荐其他同学也看看。
2022-05-0211 - ACE_Killer09repeat(3) { launch { repeat(3) { println(Thread.currentThread().name) delay(100) } } } repeat 是重复,launch是 创建协程。重复创建3个协程,每个协程执行3次,执行的内容是 打印协程执行时所在的线程。 结果说明同一个协程 可以再不同的线程上执行。
作者回复: 感谢这位同学的补充,之前代码没看懂的同学可以看看。
2022-02-1178 - _《深入理解JVM虚拟机》中提到过“协程”是“用户级线程”,不过这是从操作系统效率角度来称呼它,所以反而不太容易让“人”理解。而将“Kotlin协程”理解为“线程级Task”这种从上到下的角度要直观的多!大佬讲的很棒!👍🏻
作者回复: 加油 :)
2022-04-295 - Geek_0d808c在处理高并发,轻量任务的前提下,协程少了,线程创建的系统调用,上下文切换等时间,以及线程内存开销,是线程的复用,所以特定场景下,代价更小。
作者回复: 说得很好!线程和协程,其实在特定场景下才有可比性。
2022-02-114 - $Kotlin协程比乱用线程要高效,和合理使用线程池效率一致。
作者回复: 嗯,没错。 PS:从你的留言时间,能看出是凌晨第一时间来看的更新,对吧?加油哈!一分耕耘一分收获,总有一天,量变会产生质变。
2022-02-113 - 7Promise协程可以在适当的时机挂起和恢复,一个协程在挂起等待时,另外的协程也可以工作,比阻塞的线程更节省资源。
作者回复: 嗯,不错的理解。
2022-02-112