Kotlin Coroutine(协程)系列:
1. Kotlin Coroutine(协程) 简介
2. Kotlin Coroutine(协程) 基本知识编程
协程是可挂起计算的实例。promise
它在概念上相似于线程,在这个意义上,它须要一个代码块运行,并具备相似的生命周期,它能够被建立和启动,但它不绑定到任何特定的线程。网络
它能够在一个线程中挂起其执行,并在另外一个线程中恢复。并且,像future 或 promise那样,它在完结时可能伴随着某种结果(值或异常)异步
协程开发人员这样描述协程:异步编程
协程就像很是轻量级的线程。线程是由系统调度的,线程切换或线程阻塞的开销都比较大。而协程依赖于线程,可是协程挂起时不须要阻塞线程,几乎是无代价的,协程是由开发者控制的。因此协程也像用户态的线程,很是轻量级,一个线程中能够建立任意个协程。post
如上面所说,协程是由开发者本身控制的,所以在使用协程时咱们必定要记住一点,咱们必须知道咱们使用的协程在什么时候挂起,它又在什么时候从新恢复执行,若是无法知道这两点,那就意味着咱们没法控制协程,这个时候要慎用协程。性能
一般咱们在Android
中发起一个网络请求都会经历以下几步:spa
Retrofit.Call
Retrofit.Call.enqueue(callback)
方法上面的流程中为请求任务分配子线程通常都会配合线程池去作,以防止不断建立线程而产生系统开销,但在线程真正执行过程当中常常会遇到因磁盘IO或者是网络请求等操做而致使线程阻塞,而此时当前线程只能阻塞等待,没法作任何事情,在等待的这段时间里线程至关于白白了浪费了自身资源,致使线程自身利用率低下。线程
在Android
中改用协程发起网络请求流程以下:code
在上述流程步骤3中挂起协程后子线程并不会阻塞,此时该子线程能够被系统分配去作其余的事情,当协程挂起结束时从新在子线程中恢复执行。这样该线程就不会存在因阻塞致使的空闲浪费,提升了线程利用率。
总的来讲,使用协程能够最大程度的复用线程,经过让线程满载运行,从而达到充分的利用CPU提升系统性能。
使用协程另一个好处就是可让开发者们告别异步编程中的回调地狱,简化异步编程,让写异步代码和写同步代码同样简单,加强了代码的可读性、可理解性和可维护性。
举个例子
假定有个登陆有以下流程:
经常使用实现方式代码以下:
fun login() {
requestToken { token ->
requestUserInfo(token) { user ->
Log.i("tag", user.toString())
}
}
}
复制代码
上面的例子是Android
开发中常常会遇到的问题,一个请求依赖前一个请求的结果,这个时候常常会出现这样的写法,在第一个请求的成功回调中根据请求结果发起第二个网络请求。这里还只存在两层的嵌套,试想一下,若是嵌套层次出现4次,5次,甚至更多会出现怎样的状况,估计开发者本身写起来都会崩溃。
使用RxJava实现代码以下:
Single.fromCallable { requestToken() }
.map { token -> requestUserInfo(tokenm) }
.subscribe(
{ user -> Log.i("tag", user.toString()) }, // onSuccess
{ e -> e.printStackTrace() } // onError
)
复制代码
使用RxJava
的实现方式虽然将回调嵌套改为了链式写法,阅读起来要稍微好点,可是依然存在回调并且增长了实现的复杂度,对不熟悉RxJava
的人来讲更少增长了难度。
使用协程实现方式代码以下:
fun login() {
val token = requestToken()
val user = requestUserInfo(token)
Log.i("tag", user.toString())
}
复制代码
怎么样,使用协程的写法是否是简便不少,并且看起来很是符合人们的阅读和理解习惯。