Deep Kotlin tutorial covering launch, async, Deferred, Job with examples, diagram, mistakes, and interview answers.

launch, async, and runBlocking

What is launch, async, and runBlocking?

launch, async, and runBlocking is an important Kotlin topic from 2.3 Coroutine Builders and Structured Concurrency. In this lesson we focus only on the concepts that belong together: launch, async, Deferred, Job, runBlocking. This keeps the lesson deep enough for interviews but not mixed with unrelated ideas.

Why students should learn it

  • Understand launch, async, and runBlocking in simple language
  • Use launch in real Kotlin or Android code
  • Explain launch, async, and runBlocking in interviews with examples and trade-offs

How it works

launch, async, and runBlocking: launch, async, Deferred, Job, runBlocking works by giving asynchronous work a clear owner and execution rule. In real Android code, first identify who owns the work, then choose the dispatcher, then decide how cancellation and errors should behave. This prevents background work from continuing after the screen or ViewModel no longer needs it.

  1. Identify what problem launch, async, and runBlocking: launch, async, Deferred, Job, runBlocking solves.
  2. Write the smallest Kotlin snippet that demonstrates it.
  3. Add one Android or JVM use case where it matters.
  4. Compare it with a similar concept so the difference is clear.
  5. Finish by naming one common mistake and the safer alternative.
Interview tip: keep the answer simple first, then add example, trade-off, and mistake.

Types / Classification

  • launch: core concept in this lesson
  • async: core concept in this lesson
  • Deferred: core concept in this lesson
  • Job: core concept in this lesson
  • runBlocking: core concept in this lesson
  • Scope: owner of coroutine lifetime
  • Builder: starts coroutine work
  • Dispatcher: decides thread or pool

Important differences

Concept 1Concept 2How to remember it
suspendblockingsuspend pauses coroutine; blocking occupies a thread.
launchasynclaunch returns Job; async returns Deferred result.
scopedispatcherscope owns lifetime; dispatcher chooses execution thread.

Diagram

flowchart TD
A["2.3 Coroutine Builders and Structured Concurrency"] --> B["launch, async, and runBlocking"]
B --> C["Why it exists"]
C --> D["How it works in Kotlin"]
D --> E["Android or JVM example"]
E --> F["Mistakes and interview answer"]

Examples

ViewModel coroutine

fun refresh() {
viewModelScope.launch {
val data = withContext(Dispatchers.IO) { repository.load() }
_state.value = UiState.Content(data)
}
}

Parallel work

suspend fun loadBoth() = coroutineScope {
val profile = async { api.profile() }
val settings = async { api.settings() }
profile.await() to settings.await()
}

When to use it

Use it when: Reach for this when it makes your code clearer, safer, or easier for the next developer to follow.

Avoid it when: Skip it when a simpler, more familiar approach already solves the problem without extra ceremony.

Common mistakes

  • Using GlobalScope for screen work
  • Blocking Dispatchers.Main
  • Catching Exception and swallowing CancellationException
  • Using runBlocking in Android UI code
  • Launching work without clear ownership

Interview questions

Read each answer in four parts: simple answer, code example, trade-off, and common mistake.

1. What is launch, async, and runBlocking in 2.3 Coroutine Builders and Structured Concurrency?

Answer: launch, async, and runBlocking is an important Kotlin topic from 2.3 Coroutine Builders and Structured Concurrency. In this lesson we focus only on the concepts that belong together: launch, async, Deferred, Job, runBlocking. This keeps the lesson deep enough for interviews but not mixed with unrelated ideas.

fun refresh() {
viewModelScope.launch {
val data = withContext(Dispatchers.IO) { repository.load() }
_state.value = UiState.Content(data)
}
}
  • Trade-off: suspend and blocking solve related but different problems: suspend pauses coroutine; blocking occupies a thread.
  • Common mistake: Using GlobalScope for screen work

2. How does launch, async, and runBlocking work in Kotlin or Android code?

Answer: launch, async, and runBlocking: launch, async, Deferred, Job, runBlocking works by giving asynchronous work a clear owner and execution rule. In real Android code, first identify who owns the work, then choose the dispatcher, then decide how cancellation and errors should behave. This prevents background work from continuing after the screen or ViewModel no longer needs it.

suspend fun loadBoth() = coroutineScope {
val profile = async { api.profile() }
val settings = async { api.settings() }
profile.await() to settings.await()
}
  • Trade-off: suspend and blocking solve related but different problems: suspend pauses coroutine; blocking occupies a thread.
  • Common mistake: Blocking Dispatchers.Main

3. What is one common mistake with launch, async, and runBlocking?

Answer: A common mistake is: Using GlobalScope for screen work Another is: Blocking Dispatchers.Main

fun refresh() {
viewModelScope.launch {
val data = withContext(Dispatchers.IO) { repository.load() }
_state.value = UiState.Content(data)
}
}
  • Trade-off: suspend and blocking solve related but different problems: suspend pauses coroutine; blocking occupies a thread.
  • Common mistake: Using GlobalScope for screen work

4. How would you explain launch, async, and runBlocking with a small example?

Answer: launch, async, and runBlocking is an important Kotlin topic from 2.3 Coroutine Builders and Structured Concurrency. In this lesson we focus only on the concepts that belong together: launch, async, Deferred, Job, runBlocking. This keeps the lesson deep enough for interviews but not mixed with unrelated ideas. Here is a short example that shows it in practice.

fun refresh() {
viewModelScope.launch {
val data = withContext(Dispatchers.IO) { repository.load() }
_state.value = UiState.Content(data)
}
}
  • Trade-off: suspend and blocking solve related but different problems: suspend pauses coroutine; blocking occupies a thread.
  • Common mistake: Blocking Dispatchers.Main

5. What is the trade-off of using launch, async, and runBlocking?

Answer: suspend and blocking solve related but different problems: suspend pauses coroutine; blocking occupies a thread.

suspend fun loadBoth() = coroutineScope {
val profile = async { api.profile() }
val settings = async { api.settings() }
profile.await() to settings.await()
}
  • Trade-off: suspend and blocking solve related but different problems: suspend pauses coroutine; blocking occupies a thread.
  • Common mistake: Using GlobalScope for screen work

Practice task

Write one Kotlin example for launch, async, and runBlocking. Then explain it using: what is it, how it works, where it is used, mistake to avoid, and one interview answer.