协程-基础3
什么是协程作用域(Coroutine Scope)?
协程作用域是协程运行的作用范围,换句话说,如果这个作用域销毁了,那么里面的协程也随之失效。就好比变量的作用域。
{ // scope start
int a = 100;
} // scope end
println(a); // what is a?
协程作用域也是这样一个作用,可以用来确保里面的协程都有一个作用域的限制。
一个经典的示例就是,比如我们要在Android上使用协程,但是我们不希望Activity销毁了,我的协程还在悄咪咪的干一些事情,我希望它能停止掉。
class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
// ....
}
这样,里面运行的协程就会随着Activity的销毁而销毁。
launch的返回值:Job
回到launch的话题,launch启动后,会返回一个Job对象,表示这个启动的协程,我们可以方便的通过这个Job对象,取消,等待这个协程。
fun main() {
runBlocking(Dispatchers.IO) {
println("job1 开始了")
val job1 = launch {
for (i in 0..1) {
println("normal launch $i ${Thread.currentThread().name} #####")
delay(100)
}
}
println("job1 开始了")
val job2 = launch {
for (i in 0..1) {
println("normal launch $i ${Thread.currentThread().name} -----")
delay(100)
}
}
job1.join()
job2.join()
println("all job finished")
}
}
job1 开始了
job1 开始了
normal launch 0 DefaultDispatcher-worker-2 #####
normal launch 0 DefaultDispatcher-worker-4 -----
normal launch 1 DefaultDispatcher-worker-2 #####
normal launch 1 DefaultDispatcher-worker-4 -----
all job finished
使用job的join方法,来等待这个协程执行完毕。这个和Thread的join方法语义一样。
async:启动协程的另一种姿势
launch启动一个协程后,会返回一个Job对象,这个Job对象不含有任何数据,它只是表示启动的协程本身,我们可以通过这个Job对象来对协程进行控制。
假设这样一种场景,我需要同时启动两个协程来搞点事,然后它们分别都会计算出一个Int值,当两个协程都做完了之后,我需要将这两个Int值加在一起并输出。
async的返回值依然是个Job对象,但它可以带上返回值。
fun main() {
runBlocking(Dispatchers.IO) {
println("job1 开始了")
//
val job1 = async {
for (i in 0..2) {
println("normal launch $i ${Thread.currentThread().name} #####")
delay(100)
}
10 // TODO 注意这里的返回值
}
println("job2 开始了")
val job2 = async {
for (i in 0..2) {
println("normal launch $i ${Thread.currentThread().name} -----")
delay(100)
}
20 // TODO 注意这里的返回值
}
println(job1.await() + job2.await())
println("all job finished")
}
}
job1 开始了
job2 开始了
normal launch 0 DefaultDispatcher-worker-3 #####
normal launch 0 DefaultDispatcher-worker-2 -----
normal launch 1 DefaultDispatcher-worker-3 #####
normal launch 1 DefaultDispatcher-worker-2 -----
normal launch 2 DefaultDispatcher-worker-2 #####
normal launch 2 DefaultDispatcher-worker-5 -----
30
all job finished