协程是一种线程框架,它运行在线程上,每个协程就是一个耗时任务,协程内部程序是按顺序执行,它是一种非阻塞式的,用户可以手动控制协程的挂起和运行;
官方介绍: 协程通过将复杂性放入库来简化异步编程。程序的逻辑可以在协程中顺序地表达,而底层库会为我们解决其异步性。该库可以将用户代码的相关部分包装为回调、订阅相关事件、在不同线程(甚至不同机器)上调度执行,而代码则保持如同顺序执行一样简单;
引入
kotlin{
experimental {
coroutines 'enable'
}
}
// 协程
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
创建协程
GlobalScope.launch {
for(i in 1..3){
println("协程任务1打印: $i")
}
delay(200)
for(i in 1..3){
println("协程任务2打印: $i")
}
}
for(i in 1..3){
println("主线程打印: $i")
}
可以通过日志看到协程是按照顺序执行:
2020-05-26 15:30:58.673 24381-24381/? I/System.out: 主线程打印: 1
2020-05-26 15:30:58.673 24381-24381/? I/System.out: 主线程打印: 2
2020-05-26 15:30:58.673 24381-24381/? I/System.out: 主线程打印: 3
2020-05-26 15:30:58.674 24381-24446/? I/System.out: 协程任务1打印: 1
2020-05-26 15:30:58.674 24381-24446/? I/System.out: 协程任务1打印: 2
2020-05-26 15:30:58.674 24381-24446/? I/System.out: 协程任务1打印: 3
2020-05-26 15:30:58.878 24381-24448/? I/System.out: 协程任务2打印: 1
2020-05-26 15:30:58.878 24381-24448/? I/System.out: 协程任务2打印: 2
2020-05-26 15:30:58.878 24381-24448/? I/System.out: 协程任务2打印: 3
源码
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
val newContext = newCoroutineContext(context)
val coroutine = if (start.isLazy)
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)
coroutine.start(start, coroutine, block)
return coroutine
}
CoroutineStart: 启动模式,默认就是DEFAULT,即创建协程就启动,还有一个LAZY,懒加载模式,需要调用start才会启动;
- DEFAULT:默认模式,立即启动协程;
- ATOMIC:
- UNDISPATCHED:
- LAZY:懒加载模式,需要的时候,再启动;
block: 闭包方法体,定义协程内需要执行的操作;
Job: 创建协程的返回值,可以把job当做协程对象本身;
- start():启动协程;
- join():等待协程执行完毕;
- cancel():取消一个协程包含内部的子协程,但是async修饰的协程如果已开始则没法取消;
Suspend: 用来修饰协程的方法,被修饰的方法可以被协程挂起,suspend修饰的方法只能被suspend修饰的方法调用;
GlobalScope.async: async和launch的区别就是async有返回值
GlobalScope.launch(Dispatchers.IO){
// 多协程间 suspend函数运行
val suspend2 = GlobalScope.async(Dispatchers.IO){
return@async suspend2()
}
println("hello ${suspend2.isActive}")
println("hello ${suspend2.isActive} ${suspend2.await()}")
println("hello ${suspend2.isActive}")
// println("hello $suspend1 $suspend2 thread:${Thread.currentThread().name}")
}
打印结果
2020-05-26 19:23:42.426 9411-9485/? I/System.out: hello true
2020-05-26 19:23:42.427 9411-9487/? I/System.out: hello suspend2 start, thread:DefaultDispatcher-worker-3
2020-05-26 19:23:42.441 9411-9485/? I/System.out: hello suspend2 end, thread:DefaultDispatcher-worker-1
2020-05-26 19:23:42.442 9411-9485/? I/System.out: hello true suspend2
2020-05-26 19:23:42.442 9411-9485/? I/System.out: hello false