轻量级线程——Kotlin之协程
协程是一种“轻量级线程“,从Kotlin 1.1开始引入。由于一些耗时操作(如网络IO、文件 IO、CPU或GPU密集型任务)会使线程阻塞直到操作完成,协程提供了一种避免线程阻塞、开销更小且更加可控的异步操作。
协程的基本原理
协程完全通过编译技术实现(不需要来自 VM 或 OS 端的支持),挂起通过代码来生效。基本上,每个挂起函数都转换为状态机,其中的状态对应于挂起调用。刚好在挂起前,下一状态与相关局部变量等一起存储在编译器生成的类的字段中。在恢复该协程时,恢复局部变量并且状态机从刚好挂起之后的状态进行。
为什么需要协程
阻塞还是挂起
协程可以被挂起而不阻塞线程,线程的阻塞代价是昂贵的。尤其是创建线程数量是有限的,当线程被阻塞,那些重要的任务就有可能被延迟。协程的挂起几乎是没有代价的,它不需要切换上下文。协程的本质是最大限度的利用线程所获得的cpu时间,提高线程的效率。
协程的简单使用——launch函数
使用launch函数
public fun launch(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit): Job {}
第一个参数为协程的上下文
第二个参数为协程的启动选项
第三个参数为一个suspend修饰的函数
fun test(){
launch(Unconfined) {
delay(1000)
print("I am a Coroutine")
}
print("I am mainThread")
}
launch()函数开启了一个协程,由于协程被挂起,所以协程之外的代码先被执行,又因为协程所处的上下文已经销毁,所以不能完整执行结束。
注意:suspend函数只能用于启动协程的函数(闭包)中
launch函数返回一个Job借口对象,可以对协程进行管理。
Job接口的常用方法有
- isActive
- isCompleted
- isCanceled
- start
- cancel
- join
Job的几种状态
协程的生命周期