runBlocking and launch

Two Builders

BuilderReturnsBlocks the thread?Use it for
runBlocking { }the block resultYes, until all children finishmain(), scripts, old tests. Never on Android main thread.
launch { }JobNofire-and-forget work that returns nothing (save to DB, log, update UI)

Order of Execution

Example

launch only schedules the coroutine. It runs when the parent reaches a suspension point (here delay(50)). The numbers show the real order.

import kotlinx.coroutines.*

fun main() = runBlocking {
    println("1. runBlocking starts")
    val job = launch {
        println("3. launch body starts")
        delay(100)
        println("5. launch body ends")
    }
    println("2. launch returned immediately")
    delay(50)
    println("4. parent after 50 ms, child still waiting")
    job.join()           // wait for the child
    println("6. child finished, runBlocking ends")
}

Output

1. runBlocking starts
2. launch returned immediately
3. launch body starts
4. parent after 50 ms, child still waiting
5. launch body ends
6. child finished, runBlocking ends

Many launches

Example

Coroutines with different delays finish in delay order, all on one thread.

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch { delay(300); println("Email sent") }
    launch { delay(100); println("Order saved") }
    launch { delay(200); println("SMS sent") }
    println("All tasks started")
}   // runBlocking waits for its 3 children

Output

All tasks started
Order saved
SMS sent
Email sent

Note: runBlocking exists to bridge normal blocking code and coroutines. In an Android app you use lifecycleScope or viewModelScope instead; on a server, the framework (Ktor, Spring WebFlux) gives you a scope.