https://kotlinlang.org logo
Title
p

Pablo Schmid

06/23/2021, 4:38 PM
Hi, I'm new to coroutines and I'm trying to understand some basic behavior of async. The following code runs in 2 seconds and I understand that because I'm using async. What I don't understand is how this can happen if both asyncs are running on the same Thread (main)? Can coroutines run in parallel although they run in a single thread?
import kotlinx.coroutines.*
import kotlin.system.*
fun main() = runBlocking {
    val time = measureTimeMillis {
        println("The answer is ${concurrentSum()} en ${Thread.currentThread()}")
    }
    println("Completed in $time ms en ${Thread.currentThread()}")    
}
suspend fun concurrentSum(): Int = coroutineScope {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    one.await() + two.await()
}
suspend fun doSomethingUsefulOne(): Int {
    println("1 in Thread ${Thread.currentThread()}")
    delay(2000L) // pretend we are doing something useful here
    return 13
}
suspend fun doSomethingUsefulTwo(): Int {
    println("2 in Thread ${Thread.currentThread()}")
    delay(2000L) // pretend we are doing something useful here, too
    return 29
}
d

diesieben07

06/23/2021, 4:41 PM
Coroutines are non blocking. So the
delay
call doesn't block the thread, it merely schedules your coroutine to wake up later. So both coroutines can be "waiting" at the same time, without blocking any threads at all.
e

ephemient

06/23/2021, 4:42 PM
there wouldn't be much reason to use coroutines instead of threads if that weren't the case
z

Zach Klippenstein (he/him) [MOD]

06/23/2021, 4:43 PM
suspend fun doSomethingUsefulOne(): Int {
    println("1 in Thread ${Thread.currentThread()}")
    delay(2000L) // pretend we are doing something useful here
    return 13
}
is basically the same thing as:
fun doSomethingUsefulOne(callback: (Int) -> Unit) {
    println("1 in Thread ${Thread.currentThread()}")
    postAfterDelay(2000L) { callback(13) }
}
So
doSomethingUsefulOne
returns right away, and leaves it up to the dispatcher to eventually finish executing the rest of the function.
e

ephemient

06/23/2021, 4:44 PM
every call to a suspend fun (such as
delay
) is a suspension point, where the dispatcher can stop running your function and do something else
p

Pablo Schmid

06/23/2021, 6:00 PM
Thank you very much guys. I have a more clear picture now.