26. What Are Coroutines in Kotlin?
Coroutines in Kotlin are a modern and lightweight way to write asynchronous and non-blocking code. They simplify tasks like network requests, file I/O, or delayed operations — without blocking threads.
A coroutine is a piece of code that can suspend its execution and resume later — allowing you to write sequential-looking code that executes asynchronously under the hood.
Key Concepts:
Concept | Description |
---|---|
suspend | Marks a function that can be paused and resumed later. |
CoroutineScope | Manages lifecycle and launching of coroutines. |
launch | Starts a coroutine (returns Job) — fire and forget. |
async | Starts a coroutine (returns Deferred) — for results. |
withContext | Switches the coroutine to a different thread context. |
Example: Basic Coroutine
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000) // Non-blocking delay
println("Hello from coroutine!")
}
println("Main thread continues...")
}
Output:
Main thread continues...
Hello from coroutine!
27. Comparison with Threads and Coroutine
Feature | Thread | Coroutine |
---|---|---|
Cost | Heavyweight | Lightweight |
Memory | High | Low |
Start-up time | Slow | Fast |
Scalability | Limited (1000s max) | Can handle 100,000+ |
Blocking | Yes | No (non-blocking) |
28. Explain Suspend modifier.
In Kotlin, the suspend modifier is used to mark a function as suspendable — meaning it can be paused and resumed at a later point without blocking a thread.
A suspend function is a special kind of function that can suspend its execution to wait for a result and resume later without blocking the calling thread.
Example:
suspend fun fetchData(): String {
delay(1000) // Suspends the coroutine, doesn't block thread
return "Data fetched!"
}
fun main() = runBlocking {
val result = fetchData()
println(result)
}
delay() is a suspend function — it pauses the coroutine for 1 second without blocking the thread.
suspend fun doHeavyWork() {
withContext(Dispatchers.IO) {
// Run in IO thread
}
}
You Cannot Call suspend From Regular Code
fun normalFunction() {
fetchData() // ❌ Error: suspend function can't be called from here
}
29. What Is CoroutineScope in Kotlin?
In Kotlin, CoroutineScope defines a scope for coroutines — controlling how long coroutines run and when they should be cancelled. It's essential for managing coroutine lifecycle safely and predictably.
A CoroutineScope provides the context in which coroutines run — including the Job, Dispatcher, and lifecycle boundaries.
Example:
class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launch {
val result = fetchData()
println(result)
}
}
override fun onDestroy() {
super.onDestroy()
cancel() // Cancel all coroutines in this scope
}
}
In this example:
Creating a Scope Manually
val scope = CoroutineScope(Dispatchers.IO + Job())
scope.launch {
// Background work here
}
You can also use built-in scopes like:
GlobalScope.launch creates coroutines that live forever unless manually cancelled — which can lead to memory leaks or unexpected behavior.
Best Practices
Practice | Reason |
---|---|
Use structured scopes (MainScope, lifecycleScope) | Safer and lifecycle-aware |
Always cancel scope when needed | Prevents memory leaks |
Combine Dispatchers and Job | Full control of coroutine behavior |
30. What are the benefits of using coroutines in kotlin ?
Benefit | Traditional Threads | Coroutines |
---|---|---|
Lightweight | ❌ No | ✅ Yes |
Structured concurrency | ❌ No | ✅ Yes |
Readability | ❌ Complex | ✅ Clean syntax |
Performance | ❌ Higher memory | ✅ Efficient |
Integration | ❌ Manual | ✅ Built-in support |