目錄
1、子協程
2、父協程
1、子協程
當一個協程在其它協程在中啟動的時候, 它将通過 CoroutineScope.coroutineContext 來承襲上下文,并且這個新協程的 Job 将會成為父協程作業的 子作業。當一個父協程被取消的時候,所有它的子協程也會被遞歸的取消。
然而,當使用 GlobalScope 來啟動一個協程時,則新協程的作業沒有父作業。 是以它與這個啟動的作用域無關且獨立運作。
fun main() = runBlocking<Unit> {
// 啟動一個協程來處理某種傳入請求(request)
val request = launch {
// 孵化了兩個子作業, 其中一個通過 GlobalScope 啟動
GlobalScope.launch {
println("job1: 我用GlobalScope啟動,并且獨立執行,不受父協程影響!")
delay(1000)
println("job1: 我沒有被取消")
}
// 另一個則承襲了父協程的上下文
launch {
delay(100)
println("job2: 我是協程的孩子")
delay(1000)
println("job2: 父類被取消後,我也别取消了,是以這裡不會執行。")
}
}
delay(500)
request.cancel() // 取消請求(request)的執行
delay(1000) // 延遲一秒鐘來看看發生了什麼
}
//輸出結果
job1: 我用GlobalScope啟動,并且獨立執行,不受父協程影響!
job2: 我是協程的孩子
job1: 我沒有被取消
2、父協程
一個父協程總是等待所有的子協程執行結束。父協程并不顯式的跟蹤所有子協程的啟動,并且不必使用 Job.join 在最後的時候等待它們完成。
fun main() = runBlocking<Unit> {
// 啟動一個協程來處理某種傳入請求(request)
val request = launch {
repeat(3) { i -> // 啟動少量的子作業
launch {
delay((i + 1) * 200L) // 延遲 200 毫秒、400 毫秒、600 毫秒的時間
println("協程 $i 執行完成")
}
}
println("request: 父協程執行完成,但是我的子協程仍然活着,直到它們執行完成")
}
request.join() // 等待請求的完成,包括其所有子協程
println("現在所有的協程都執行完成了")
}
//輸出結果
request: 父協程執行完成,但是我的子協程仍然活着,直到它們執行完成
協程 0 執行完成
協程 1 執行完成
協程 2 執行完成
現在所有的協程都執行完成了