Kotlin Tutorial · Advanced Kotlin · Lesson 26 of 31
Kotlin Coroutines
Write asynchronous code that reads like sequential code with suspend functions, launch, async and structured concurrency.
suspend functions
A suspend function can pause without blocking its thread (for example while waiting for the network) and resume
later. Coroutines come from the kotlinx.coroutines library
(implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0")).
runBlockingbridges normal code and coroutines (used inmainand tests).launchstarts a coroutine that returns nothing;asyncstarts one that returns aDeferredyouawait.delaysuspends without blocking a thread.
import kotlinx.coroutines.*
import kotlin.time.measureTime
suspend fun fetchUser(): String {
delay(300) // pretend network call
return "Ana"
}
suspend fun fetchOrders(): Int {
delay(300)
return 3
}
fun main() = runBlocking {
val elapsed = measureTime {
val user = async { fetchUser() } // both start now
val orders = async { fetchOrders() }
println("${user.await()} has ${orders.await()} orders")
}
println(if (elapsed.inWholeMilliseconds < 550) "ran concurrently" else "ran sequentially")
launch { println("background job done") }
println("main continues")
}
Output
Ana has 3 orders ran concurrently main continues background job done
Run this on your computer — see “Get Started” for setup.
Structured concurrency
Coroutines run inside a scope. A scope waits for its children, and if one child fails, the others are
cancelled and the error reaches the caller: no leaked background work. withTimeout cancels slow work.
import kotlinx.coroutines.*
suspend fun loadAll(): List<String> = coroutineScope {
val a = async { delay(100); "profile" }
val b = async { delay(50); throw IllegalStateException("orders service down") }
listOf(a.await(), b.await())
}
fun main() = runBlocking {
try {
loadAll()
} catch (e: IllegalStateException) {
println("failed: ${e.message}; the profile request was cancelled too")
}
val result = withTimeoutOrNull(200) {
delay(1_000)
"slow result"
}
println(result ?: "timed out")
}
Output
failed: orders service down; the profile request was cancelled too timed out
Run this on your computer — see “Get Started” for setup.
Test yourself
What happens to sibling coroutines when one child fails inside coroutineScope?
They keep runningThey are cancelled and the exception propagates to the callerThe program exitsThe failure is ignored
Show answer
Answer: They are cancelled and the exception propagates to the caller