Kotlin
Kotlin coroutines overview
Coroutines are Kotlin's answer to asynchronous programming. They let you write concurrent code that reads sequentially, without blocking threads.
Suspend functions
A suspend function can pause and resume without blocking the underlying thread. It can only be called from a coroutine or another suspend function.
suspend fun fetchUser(id: String): User {
delay(100) // suspends, does not block the thread
return api.getUser(id)
}
Launching coroutines
You need a CoroutineScope. launch fires a job that returns nothing, async returns a Deferred you can await.
scope.launch {
val user = fetchUser('42')
println(user.name)
}
val a = scope.async { fetchUser('1') }
val b = scope.async { fetchUser('2') }
val both = listOf(a.await(), b.await()) // runs concurrently
Dispatchers
A dispatcher decides which thread pool the work runs on.
| Dispatcher | Use for |
|---|---|
| Dispatchers.Main | UI updates |
| Dispatchers.IO | network and disk |
| Dispatchers.Default | CPU-heavy work |
withContext(Dispatchers.IO) {
file.readText()
}
Structured concurrency
This is the big idea. A coroutine launched in a scope is a child of that scope. If the scope is cancelled, all children are cancelled. If a child fails, siblings are cancelled too. You cannot leak a coroutine that outlives its scope, which prevents a whole category of bugs.
On Android, prefer viewModelScope and lifecycleScope so coroutines are cancelled automatically when the screen goes away.
Cancellation is cooperative
Cancellation only works if your code checks for it. Suspend functions from the standard library do this for you; long CPU loops should call ensureActive() or yield() periodically.
