This Kotlin Coroutine Builders tutorial explains how to use launch, async, withContext, and runBlocking to manage asynchronous tasks efficiently. The chapter focuses on practical examples, structured concurrency, and best practices to help developers write clean, non-blocking, and maintainable Kotlin code.
Coroutine Builders in Kotlin (Complete Tutorial)
Coroutine Builders Overview
Coroutine builders are functions that start new coroutines. Each builder serves a specific purpose depending on whether you need a return value, thread switching, or blocking behavior.
launch
launch starts a new coroutine that does not return a result. It returns a Job.
Use Case
- Fire-and-forget tasks
- Background operations
- UI updates
Example
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
delay(1000L)
println("Task completed")
}
job.join()
println("Main continues")
}
Best Practices
- Use
launchwhen you don’t need a result. - Always manage the
Joblifecycle.
async
async starts a coroutine that returns a result using Deferred<T>.
Use Case
- Parallel computations
- When a result is required
Example
import kotlinx.coroutines.*
fun main() = runBlocking {
val deferred = async {
delay(1000L)
10 + 20
}
println("Result: ${deferred.await()}")
}
Best Practices
- Always call
await()to get the result. - Use
asyncinside a structured scope.
launch vs async
| Featurelaunchasync | ||
| Returns value | No | Yes |
| Return type | Job | Deferred<T> |
| Use case | Background tasks | Parallel tasks |
withContext
withContext switches the coroutine context without creating a new coroutine.
Use Case
- Switching threads
- Performing I/O or CPU tasks safely
Example
import kotlinx.coroutines.*
fun main() = runBlocking {
val result = withContext(Dispatchers.IO) {
delay(500L)
"Data loaded"
}
println(result)
}
Best Practices
- Prefer
withContextover nestedlaunch. - Use for context switching only.
runBlocking
runBlocking blocks the current thread until execution completes.
Use Case
- Main functions
- Testing
- Learning and demos
Example
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(500L)
println("Inside coroutine")
}
println("runBlocking active")
}
Best Practices
- Avoid
runBlockingin production code. - Never use it in Android UI threads.
Real-World Example: Parallel API Calls
import kotlinx.coroutines.*
suspend fun fetchUser(): String {
delay(1000L)
return "User"
}
suspend fun fetchOrders(): String {
delay(1000L)
return "Orders"
}
fun main() = runBlocking {
val user = async { fetchUser() }
val orders = async { fetchOrders() }
println("${user.await()} with ${orders.await()}")
}
Summary
This chapter covered Kotlin coroutine builders including launch, async, withContext, and runBlocking. Understanding when and how to use each builder is essential for writing efficient, concurrent, and structured Kotlin applications.