我正在尝试理解Kotlin中的结构化并发,但我无法理解这段代码。
fun main(): Unit = runBlocking {
other(this)
}
suspend fun other(scope: CoroutineScope) {
val job = scope.launch {
scope.launch {
delay(200)
println("e")
}
println("a")
}
job.invokeOnCompletion {
println("Complete")
}
}
代码打印
a
Complete
e
如果我用launch
替换内部的scope.launch
调用,如下所示
suspend fun other(scope: CoroutineScope) {
val job = scope.launch {
launch {
delay(200)
println("e")
}
println("a")
}
job.invokeOnCompletion {
println("Complete")
}
}
它打印
a
e
Complete
这表明第一个例子没有遵循结构化并发,因为父作业在子作业之前完成。我的困惑是,为什么会发生这种情况?
我觉得scope.launch
在这种情况下可能等同于调用launch
(应该等同于this.launch
,这里指的是scope
)。但似乎不是这样。有人能解释一下为什么第一个会导致非结构化并发,以及两个启动调用之间的区别吗?谢谢!
1条答案
按热度按时间euoag5mw1#
在第一段代码中,虽然内部启动看起来像是外部启动的子进程,但实际上它不是--它是外部启动的兄弟进程,因为它们都是从同一个作用域启动的。因此,等待外部启动的任务完成并不是等待内部启动。
第二段代码使用结构化并发,因为内部启动使用外部启动(启动块的接收者)创建的作用域,在这种情况下,它是外部启动的子作业,因此等待外部作业完成也要等待子作业完成。
第二个是你应该做的:使用启动块的CoroutineScope接收器来启动子作业。2使用其他作用域并不能提供结构化并发。