「协程」和「Kotlin 协程」

Tips 0:写彻底文回头看,我以为只看总结也够了。能够快进。html

前言

最初接触 Kotlin 的时候,Kotlin 协程还处于实验阶段,我也是第一次据说协程的概念。几年过去了,随着 Kotlin 的推广和 Kotlin 协程的发展,我终于在去年年末正式入坑了。web

大约5个月的时间,从 demo 用到真实项目,我对 Kotlin 协程的见解也一波三折,从不明觉厉到不过如此,又逐渐变成这东西真不错。编程

关于 Kotlin 协程我有不少想写的内容,草稿箱和笔记里都有不一样的提纲,但第一篇就仍是从困扰了我最久的点开始讲起吧,那就是「协程」的概念和 Kotlin 中的协程。markdown

本文中协程和 Kotlin 协程是两种并列的不一样的概念,两者没有包含关系。并发

从协程的概念开始

Tips 1:对于还未接触过协程的人来讲,我以为学习 Kotlin 协程彻底不须要去深刻理解协程自己的概念,由于 Kotlin 协程并非真正的协程,早期过分研究概念和对比区别是学习 Kotlin 协程的一条弯路。app

根据维基百科的介绍,协程并非新技术,这个概念正式发布于1963年,是一种实现多任务并发的技术思路,大概与「线程」位于同一级别,两者的区别则是线程采起「抢占式」策略,而协程采起「协做式」策略。框架

单从概念上看,协程可控性比线程高,彷佛是更优解,但协做式的方案不能实现真正的并行,很显然,线程取得了胜利。异步

「协程」一度沉寂,但随着软件开发的复杂度提高,不少语言都从新捡起了协程的概念来处理异步操做,但具体实现上已经与曾经的协程相去甚远。异步编程

Kotlin 协程的目标

Kotlin 协程是一个 JetBrains 官方出品的库,但不包含在 Kotlin 语言标准库中,目标是解决开发者用很差线程的问题(我编的)。函数

根据官方介绍,Kotlin 协程是用来实现异步任务和非阻塞编程的。以 Android 开发为例,为了保证良好的用户体验,系统规定 UI 线程不可阻塞,以便马上响应用户输入,全部耗时操做都应该在其余线程实现,再通知 UI 线程更新页面。不仅是 Android,全部对外提供服务的程序都有这样的需求,给了 Kotlin 协程更普遍的发挥空间。

Kotlin 协程的功能

Kotlin 的协程使用了协程的概念,经过「挂起」和「恢复」简化了多任务协做的实现代码。Kotlin 协程是一种对同步编程和异步编程统一的抽象封装。

  • 挂起和恢复

挂起和恢复来自协程的基本概念,每一个协程自身决定什么时候挂起什么时候继续,达成多任务之间协做。

image.png

在一次次调用 suspend 函数的过程当中,表面上连续的调用栈实际上已经完成了线程切换。

被挂起和恢复的对象是协程,也就是说在第一次 suspend 以后线程 A 并未被阻塞,还能够执行其余发生在线程 A 的代码。

  • 多任务

任务是一种抽象概念,能够理解成一段代码或者一个函数,执行任务须要必定的时间,任务可能正常完成得到须要的结果,也可能遇到异常而失败。Kotlin 协程的协做是多任务之间的协做,任务一般在不一样的线程,但也能够在相同的线程。(一个挂起函数内也能够调用普通函数)

  • 关于简化

只看官方对 Kotlin 协程的介绍可能以为简化的做用很大,其实那些例子都没有处理 Exception,实际应用协程的时候并不会那么简单。但简化代码并非虚假宣传,实际上简化的是恢复的过程,协程恢复的过程是将其余任务的处理结果传回来的地方,若是使用回调的话,免不了加一层嵌套,任务越多越复杂。Kotlin 协程的简化是把这些嵌套拉平了。

一段总结

写完以后我又反复读了文章内容,不断修改,但仍是以为漏洞百出。讲述概念的每一处用词都通过了反复推敲,但仍是会发现先后矛盾、内容重复、歧义等问题。有点只可意会不可言传的意思了。

总结一下观点吧:

  1. 当对比协程和线程时,一般是指概念上的协程,与 Kotlin 协程不是同一个东西
  2. Kotlin 协程是一个用协程概念在线程框架上封装的库
  3. Kotlin 协程能够解决异步代码难写难读的问题,但并不是不可替代的黑科技

投降了,讲概念太可怕了,下一篇写 Kotlin 协程和 ViewModel、Retrofit、Room 的实践。


参考资料:

  1. 协程-维基百科
  2. Coroutine|Kotlin
  3. 《深刻理解 Kotlin 协程》

Tips 2: 《深刻理解 Kotlin 协程》这本书经过横向对比不一样语言的协程实现,或者不一样异步任务实现方案阐述了 Kotlin 协程的各方面特色,也有对源码的一些讲解,重理论轻实践,最好在有必定的实践经验以后再看。