Coroutines in Kotlin provide a lightweight and powerful solution for asynchronous and concurrent programming. While platforms like Android have traditionally used tools like AsyncTask (now deprecated), ThreadPoolExecutor, or RxJava, Kotlin coroutines offer a modern alternative built into the language. They avoid callback hell, use less memory (lightweight) and CPU resources (smart scheduling), reduce memory leaks, and are easier to manage.
Coroutines allow concurrent code execution without blocking threads. They are not threads themselves, but rather lightweight code blocks that are executed on threads and can suspend and resume without blocking those threads. This enables thousands of coroutines to run efficiently on a limited number of threads — making them ideal for server applications, Android apps, desktop tools, and more.
Main Coroutine Features
- Coroutines are not tied to specific threads — they can suspend on one thread and resume on another.
- Multiple coroutines can run on a single thread due to suspending functions, which do not block threads and allow coroutine code to pause and resume efficiently using a coroutine context.
-
Coroutines must run inside a Coroutine Scope, which defines their context and manages lifecycle. Canceling a scope will cancel all coroutines within it.
Common scopes include:
- GlobalScope — lives as long as the application
- CoroutineScope — tied to a user-defined lifecycle
- runBlocking — blocks the current thread until execution completes
- Android-specific: lifecycleScope (Activity/Fragment) and viewModelScope (ViewModel)
-
Coroutines can be assigned to different dispatchers, which determine the thread(s) they run on:
- Dispatchers.Default — CPU-intensive tasks
- Dispatchers.IO — File, network, or database access
- Dispatchers.Main — Main thread (Android UI)
- Dispatchers.Unconfined — Not confined to any thread
-
Coroutines are launched using builder functions:
- runBlocking — Starts coroutine and blocks current thread
- launch — Launches a coroutine without returning a result
- async — Launches a coroutine and returns a result via
Deferred
Kotlin's suspend Function
A suspend function is a special Kotlin function that can be paused and resumed. It is declared using the suspend keyword and can only be called from
another suspend function or within a coroutine.
Suspending a function does not block the thread; it simply pauses the coroutine's execution until the result is ready, freeing the thread to do other work.
Note: In Android, calling a suspend function directly inside onCreate() or other lifecycle methods is not allowed. You must launch a coroutine first.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Launch coroutine
GlobalScope.launch {
// Call suspend function here or from another suspend function
}
}
}
Quiz Questions
- Coroutines are considered light-weight threads. While threads are managed by the OS, are coroutines managed the same way?
- Can a coroutine launched in GlobalScope be canceled before the application shuts down?