Hello!
I’m struggle with understanding what’s the difference between two code snippets (except syntax ;)) and why those two scenarios give different results.
Let’s consider we have a blocking function which I’m going to use in two examples:
private fun randomIntBlocking(): Int {
Thread.sleep(1000)
val randomValue = Random.nextInt()
println("${Thread.currentThread().name} - I'm done! $randomValue")
return randomValue
}
- Scenario 1:
@Test
fun `async - async in the main function`() = runBlocking {
val deferred1 = async(Dispatchers.Default) { randomIntBlocking() }
val deferred2 = async(Dispatchers.Default) { randomIntBlocking() }
val deferred3 = async(Dispatchers.Default) { randomIntBlocking() }
println(deferred1.await())
println(deferred2.await())
println(deferred3.await())
}
If I run this code all executions of randomIntBlocking
are done in parallel and we’ve got the output:
DefaultDispatcher-worker-1 @coroutine#2 - I'm done! 1934764997
DefaultDispatcher-worker-3 @coroutine#4 - I'm done! -144097372
DefaultDispatcher-worker-2 @coroutine#3 - I'm done! 541287634
1934764997
541287634
-144097372
- Scenario 2
@Test
fun `async - function internal async`() = runBlocking {
val deferred1 = asyncFunctionWithDispatcher()
val deferred2 = asyncFunctionWithDispatcher()
val deferred3 = asyncFunctionWithDispatcher()
val deferred4 = asyncFunctionWithDispatcher()
println(deferred1.await())
println(deferred2.await())
println(deferred3.await())
println(deferred4.await())
}
suspend fun asyncFunctionWithDispatcher(): Deferred<Int> = coroutineScope {
println("${Thread.currentThread().name} - before async")
async(Dispatchers.Default) { randomIntBlocking() }
}
However,in this case, all randomIntBlocking()
are done sequantially
main @coroutine#1 - before async
DefaultDispatcher-worker-1 @coroutine#2 - I'm done! -696818037
main @coroutine#1 - before async
DefaultDispatcher-worker-1 @coroutine#3 - I'm done! 546231453
main @coroutine#1 - before async
DefaultDispatcher-worker-1 @coroutine#4 - I'm done! -1402903086
-696818037
546231453
-1402903086
I can see that in the second scenario only one worker thread is used. What is the essential difference between those two snippets?