Skip to content
suspend Functions and Builders
step 1/5

Reading — step 1 of 5

Learn

~1 min readCoroutines

Coroutines are Kotlin's lightweight async primitive. Cooperative, structured, and orders of magnitude cheaper than threads.

A coroutine is suspended with suspend functions:

import kotlinx.coroutines.*

suspend fun fetchUser(id: Int): User {
    delay(100)         // suspend, doesn't block thread
    return database.getUser(id)
}

suspend functions can only be called from other suspend functions, OR from a coroutine builder that creates a scope.

Builders:

  • runBlocking { ... } — bridges blocking and coroutine code (use only in main / tests)
  • launch { ... } — fire-and-forget, returns a Job
  • async { ... } — returns Deferred<T> (like Promise)
  • withContext(ctx) { ... } — switch dispatcher mid-coroutine
fun main() = runBlocking {
    val user = async { fetchUser(1) }
    val settings = async { fetchSettings(1) }

    println("${user.await()} : ${settings.await()}")
}

Both fetches run in parallel. await() yields until ready.

Dispatchers decide what thread runs the coroutine:

  • Dispatchers.Default — CPU-bound work; pool sized to cores
  • Dispatchers.IO — blocking I/O; pool sized larger
  • Dispatchers.Main — UI thread (Android/Swing/JavaFX)
  • Dispatchers.Unconfined — runs on whatever thread suspended (use rarely)

Structured concurrency — coroutines launched in a scope are automatically cancelled if the scope ends. No leaked tasks.

coroutineScope {
    launch { task1() }
    launch { task2() }
    // both finish before this block returns
    // if either fails, both are cancelled
}

This is Kotlin's killer feature over Java's CompletableFuture: cancellation propagation.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…