Kotlin Coroutines
Asynchronous programming made simple and efficient
β‘ What are Kotlin Coroutines?
Coroutines enable asynchronous programming by allowing functions to pause and resume execution without blocking threads. They make concurrent code simple, readable, and efficient for handling long-running operations like network requests and file processing.
import kotlinx.coroutines.*
// Simple coroutine example
suspend fun fetchData(): String {
delay(1000) // Simulates network delay
return "Data loaded!"
}
// Usage in main function
runBlocking {
println("Starting...")
val data = fetchData()
println(data)
}
Output:
Starting...
Data loaded!
Coroutine Concepts
Suspend Functions
Functions that can pause and resume
suspend fun doWork()
Launch
Start coroutines without blocking
launch { /* async work */ }
Async/Await
Concurrent execution with results
async { computation() }
Delay
Non-blocking pause execution
delay(1000)
πΉ Basic Coroutines
Creating and running simple coroutines:
import kotlinx.coroutines.*
fun basicCoroutineExample() = runBlocking {
println("Main program starts: ${Thread.currentThread().name}")
// Launch a coroutine
launch {
delay(1000)
println("World! ${Thread.currentThread().name}")
}
println("Hello, ${Thread.currentThread().name}")
delay(2000) // Keep main alive
println("Main program ends")
}
// Suspend function example
suspend fun doSomethingUseful(): Int {
println("Doing something useful...")
delay(1000) // Pretend we are doing something useful here
return 42
}
fun suspendFunctionExample() = runBlocking {
val result = doSomethingUseful()
println("Result: $result")
}
basicCoroutineExample()
suspendFunctionExample()
Output:
Main program starts: main
Hello, main
World! main
Main program ends
Doing something useful...
Result: 42
πΉ Async and Await
Run multiple operations concurrently:
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis
suspend fun fetchUserData(userId: Int): String {
delay(1000) // Simulate network call
return "User$userId data"
}
suspend fun fetchUserPosts(userId: Int): String {
delay(1500) // Simulate network call
return "User$userId posts"
}
fun concurrentExample() = runBlocking {
val time = measureTimeMillis {
// Sequential execution (slow)
println("=== Sequential ===")
val userData = fetchUserData(1)
val userPosts = fetchUserPosts(1)
println("$userData and $userPosts")
}
println("Sequential took: ${time}ms")
val concurrentTime = measureTimeMillis {
// Concurrent execution (fast)
println("=== Concurrent ===")
val userDataDeferred = async { fetchUserData(2) }
val userPostsDeferred = async { fetchUserPosts(2) }
val userData = userDataDeferred.await()
val userPosts = userPostsDeferred.await()
println("$userData and $userPosts")
}
println("Concurrent took: ${concurrentTime}ms")
}
concurrentExample()
Output:
=== Sequential ===
User1 data and User1 posts
Sequential took: 2500ms
=== Concurrent ===
User2 data and User2 posts
Concurrent took: 1500ms
πΉ Coroutine Scopes
Managing coroutine lifecycles with scopes:
import kotlinx.coroutines.*
fun scopeExample() = runBlocking {
println("=== Coroutine Scope Example ===")
// Create a custom scope
val job = Job()
val scope = CoroutineScope(Dispatchers.Default + job)
// Launch multiple coroutines in the scope
repeat(3) { i ->
scope.launch {
delay(100L * i)
println("Coroutine $i completed")
}
}
delay(500) // Wait for coroutines to complete
// Cancel all coroutines in the scope
println("Cancelling scope...")
job.cancel()
// Try to launch after cancellation
try {
scope.launch {
println("This won't execute")
}
} catch (e: Exception) {
println("Cannot launch in cancelled scope")
}
}
// Exception handling in coroutines
fun exceptionHandlingExample() = runBlocking {
println("=== Exception Handling ===")
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught exception: ${exception.message}")
}
val job = launch(handler) {
delay(100)
throw RuntimeException("Something went wrong!")
}
job.join()
println("Program continues...")
}
scopeExample()
exceptionHandlingExample()
Output:
=== Coroutine Scope Example ===
Coroutine 0 completed
Coroutine 1 completed
Coroutine 2 completed
Cancelling scope...
=== Exception Handling ===
Caught exception: Something went wrong!
Program continues...