Hi, I'm new to coroutines and I'm trying to unders...
# coroutines
p
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?
Copy code
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
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
there wouldn't be much reason to use coroutines instead of threads if that weren't the case
z
Copy code
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:
Copy code
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
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
Thank you very much guys. I have a more clear picture now.