什么是協(xié)程作用域(Coroutine Scope)?
協(xié)程作用域是協(xié)程運(yùn)行的作用范圍,換句話說,如果這個作用域銷毀了,那么里面的協(xié)程也隨之失效。就好比變量的作用域。
{ // scope start
int a = 100;
} // scope end
println(a); // what is a?
協(xié)程作用域也是這樣一個作用,可以用來確保里面的協(xié)程都有一個作用域的限制。
一個經(jīng)典的示例就是,比如我們要在Android上使用協(xié)程,但是我們不希望Activity銷毀了,我的協(xié)程還在悄咪咪的干一些事情,我希望它能停止掉。
class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
// ....
}
這樣,里面運(yùn)行的協(xié)程就會隨著Activity的銷毀而銷毀。
launch的返回值:Job
回到launch的話題,launch啟動后,會返回一個Job對象,表示這個啟動的協(xié)程,我們可以方便的通過這個Job對象,取消,等待這個協(xié)程。
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方法,來等待這個協(xié)程執(zhí)行完畢。這個和Thread的join方法語義一樣。
async:啟動協(xié)程的另一種姿勢
launch啟動一個協(xié)程后,會返回一個Job對象,這個Job對象不含有任何數(shù)據(jù),它只是表示啟動的協(xié)程本身,我們可以通過這個Job對象來對協(xié)程進(jìn)行控制。
假設(shè)這樣一種場景,我需要同時啟動兩個協(xié)程來搞點事,然后它們分別都會計算出一個Int值,當(dāng)兩個協(xié)程都做完了之后,我需要將這兩個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