SyntaxStudy
Sign Up
Kotlin async/await and Parallel Decomposition
Kotlin Beginner 1 min read

async/await and Parallel Decomposition

The async coroutine builder is like launch but returns a Deferred, which is a future-like object holding a result. You retrieve the result by calling await(), which suspends the current coroutine until the Deferred completes without blocking any thread. The key use case for async is parallel decomposition: starting multiple async blocks simultaneously and then awaiting all of them to combine results. If both operations take one second each, running them in parallel takes one second total rather than two. awaitAll() is a convenient extension that awaits a list of Deferred objects in parallel and returns a list of results. coroutineScope ensures that if any child throws an exception, all other children in the scope are cancelled automatically.
Example
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis

suspend fun fetchUser(id: Int): String {
    delay(500)   // simulate network call
    return "User#$id"
}

suspend fun fetchScore(userId: String): Int {
    delay(300)   // simulate DB query
    return userId.length * 10
}

fun main() = runBlocking {
    // Sequential — ~800 ms
    val seqMs = measureTimeMillis {
        val user  = fetchUser(1)
        val score = fetchScore(user)
        println("Sequential: $user -> $score")
    }
    println("Sequential took: ${seqMs}ms")

    // Parallel with async/await — ~500 ms
    val parMs = measureTimeMillis {
        val deferredUser  = async { fetchUser(1) }
        val deferredUser2 = async { fetchUser(2) }

        val user1 = deferredUser.await()
        val user2 = deferredUser2.await()
        println("Parallel: $user1 and $user2")
    }
    println("Parallel took: ${parMs}ms")

    // awaitAll on a list
    val users = (1..5).map { id -> async { fetchUser(id) } }.awaitAll()
    println("All users: $users")

    // async with explicit start (lazy)
    val lazy = async(start = CoroutineStart.LAZY) { fetchUser(99) }
    println("Lazy not started yet")
    println(lazy.await())   // starts here
}