[英]Kotlin Coroutine Launch inside another launch getting called sequentially
我有 2 个通过启动调用的挂起方法,这两个方法都通过启动创建了更多的协程。 我看到结果是连续的。 如果我删除第二级启动,那么我会看到这些操作是并行执行的。 有人可以解释为什么这不是以异步/并行方式运行吗?
private suspend fun coroutineA() = coroutineScope {
println("[${printThreadInfo()}] Starting coroutineA()")
(1..10).forEach {
launch {
delay(1000)
println("[${printThreadInfo()}] A$it")
}
}
}
private suspend fun coroutineB() = coroutineScope {
println("[${printThreadInfo()}] Starting coroutineB()")
(1..10).forEach {
launch {
delay(1000)
println("[${printThreadInfo()}] B$it")
}
}
}
// -Dkotlinx.coroutines.debug
fun main() {
runBlocking {
launch {
println("[${printThreadInfo()}] Launching coroutineA")
coroutineA()
}
launch {
println("[${printThreadInfo()}] Launching coroutineB")
coroutineB()
}
}
}
我看到的结果是:
[2020-11-20T07:53:17.749 Thread=main] Start of main()
[2020-11-20T07:53:17.859 Thread=main @coroutine#1] Launching launchMultipleCoroutines
[2020-11-20T07:53:17.866 Thread=main @coroutine#2] Launching coroutineA
[2020-11-20T07:53:17.868 Thread=main @coroutine#2] Starting coroutineA()
[2020-11-20T07:53:17.871 Thread=main @coroutine#3] Launching coroutineB
[2020-11-20T07:53:17.872 Thread=main @coroutine#3] Starting coroutineB()
[2020-11-20T07:53:18.878 Thread=main @coroutine#4] A1
[2020-11-20T07:53:18.878 Thread=main @coroutine#5] A2
[2020-11-20T07:53:18.878 Thread=main @coroutine#6] A3
[2020-11-20T07:53:18.879 Thread=main @coroutine#7] A4
[2020-11-20T07:53:18.879 Thread=main @coroutine#8] A5
[2020-11-20T07:53:18.879 Thread=main @coroutine#9] A6
[2020-11-20T07:53:18.879 Thread=main @coroutine#10] A7
[2020-11-20T07:53:18.879 Thread=main @coroutine#11] A8
[2020-11-20T07:53:18.880 Thread=main @coroutine#12] A9
[2020-11-20T07:53:18.880 Thread=main @coroutine#13] A10
[2020-11-20T07:53:18.880 Thread=main @coroutine#14] B1
[2020-11-20T07:53:18.880 Thread=main @coroutine#15] B2
[2020-11-20T07:53:18.880 Thread=main @coroutine#16] B3
[2020-11-20T07:53:18.880 Thread=main @coroutine#17] B4
[2020-11-20T07:53:18.881 Thread=main @coroutine#18] B5
[2020-11-20T07:53:18.881 Thread=main @coroutine#19] B6
[2020-11-20T07:53:18.881 Thread=main @coroutine#20] B7
[2020-11-20T07:53:18.881 Thread=main @coroutine#21] B8
[2020-11-20T07:53:18.881 Thread=main @coroutine#22] B9
[2020-11-20T07:53:18.881 Thread=main @coroutine#23] B10
而如果我删除 coroutineA 和 coroutineB 中的 launch(),我会看到结果看起来像是并行执行的:
[2020-11-20T08:02:49.356 Thread=main @coroutine#2] Launching coroutineA
[2020-11-20T08:02:49.407 Thread=main @coroutine#2] Starting coroutineA()
[2020-11-20T08:02:49.415 Thread=main @coroutine#3] Launching coroutineB
[2020-11-20T08:02:49.415 Thread=main @coroutine#3] Starting coroutineB()
[2020-11-20T08:02:49.512 Thread=main @coroutine#2] A1
[2020-11-20T08:02:49.516 Thread=main @coroutine#3] B1
[2020-11-20T08:02:49.612 Thread=main @coroutine#2] A2
[2020-11-20T08:02:49.617 Thread=main @coroutine#3] B2
[2020-11-20T08:02:49.716 Thread=main @coroutine#2] A3
[2020-11-20T08:02:49.718 Thread=main @coroutine#3] B3
[2020-11-20T08:02:49.817 Thread=main @coroutine#2] A4
[2020-11-20T08:02:49.819 Thread=main @coroutine#3] B4
[2020-11-20T08:02:49.921 Thread=main @coroutine#2] A5
...
发现我们需要使用launch(Dispatchers.Default)
来实现协程的并行运行。 显示上下文有助于缩小范围。
[2020-11-20T08:47:47.858 Thread=main @coroutine#2] [[CoroutineId(2), "coroutine#2":StandaloneCoroutine{Active}@3d04a311, BlockingEventLoop@7a46a697]] Launching coroutineA
[2020-11-20T08:47:47.912 Thread=main @coroutine#2] [[CoroutineId(2), "coroutine#2":ScopeCoroutine{Active}@57fa26b7, BlockingEventLoop@7a46a697]] Starting coroutineA()
[2020-11-20T08:47:47.921 Thread=main @coroutine#3] Launching coroutineB
[2020-11-20T08:47:47.922 Thread=main @coroutine#3] [[CoroutineId(3), "coroutine#3":ScopeCoroutine{Active}@44e81672, BlockingEventLoop@7a46a697]] Starting coroutineB()
[2020-11-20T08:47:48.929 Thread=DefaultDispatcher-worker-6 @coroutine#17] [[CoroutineId(17), "coroutine#17":StandaloneCoroutine{Active}@7e782624, Dispatchers.Default]] B4
[2020-11-20T08:47:48.929 Thread=DefaultDispatcher-worker-5 @coroutine#4] [[CoroutineId(4), "coroutine#4":StandaloneCoroutine{Active}@28a58b8f, Dispatchers.Default]] A1
添加调度程序类型从 blocksEvenLoop 更改为独立协程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.