Reputation: 2006
I have 2 suspend methods invoked via launch and both of those methods creates further coroutines via launch. I see the results are sequential. If I remove the second level launch, then I see that the operations are executed in parallel. Can someone throw light on why this isn't being run in async/parallel?
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()
}
}
}
The result I see is:
[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
whereas if I remove the launch() inside coroutineA and coroutineB, I see that the results looks like executed in parallel:
[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
...
Upvotes: 1
Views: 2288
Reputation: 2006
Figured out that we need to use launch(Dispatchers.Default)
to achieve the coroutine running in parallel.
Displaying the context helped in narrowing down.
[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
Adding the dispatcher type changes from blockingEvenLoop to standalone coroutine.
Upvotes: 3