100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Kotlin

Coroutines in Kotlin

Understand how Kotlin coroutines enable lightweight asynchronous programming using suspend functions and builders.

Coroutines & Error HandlingIntermediate10 min readJul 8, 2026
Analogies

Introduction

Coroutines are Kotlin's approach to writing asynchronous and concurrent code that looks sequential and is easy to reason about. They are lightweight compared to threads, meaning thousands of coroutines can run on just a handful of OS threads. Coroutines are not part of Kotlin's core standard library; they are provided by the kotlinx.coroutines library, which builds on language features like suspend functions.

🏏

Cricket analogy: Coroutines are like a stadium running thousands of fan queue-lines through just a handful of ticket gates (OS threads): each queue pauses and resumes at the gate without needing its own dedicated turnstile, unlike heavy dedicated-thread gates.

Syntax

kotlin
suspend fun fetchData(): String {
    // can be paused and resumed without blocking a thread
    return "data"
}

CoroutineScope(Dispatchers.IO).launch {
    val result = fetchData()
    println(result)
}

Explanation

A suspend fun marks a function that can be paused and resumed later without blocking the underlying thread. Coroutines are launched inside a CoroutineScope using builders such as launch, which is fire-and-forget and returns a Job, or async, which returns a Deferred<T> whose result is retrieved with .await(). runBlocking bridges regular blocking code with coroutine code and is mainly used in main functions or tests. Dispatchers like Dispatchers.Main, Dispatchers.IO, and Dispatchers.Default determine which thread pool a coroutine actually executes on.

🏏

Cricket analogy: A suspend fun reviewing a DRS replay pauses without freezing the whole match; launch is like sending a fielder to fetch water (fire-and-forget, returns a Job), async is like requesting a stat from the analyst you'll collect later via .await(), and Dispatchers.IO decides which support staff handles it.

Example

kotlin
import kotlinx.coroutines.*

suspend fun fetchUser(): String {
    delay(1000L)
    return "Alice"
}

suspend fun fetchScore(): Int {
    delay(1000L)
    return 95
}

fun main() = runBlocking {
    val userDeferred = async { fetchUser() }
    val scoreDeferred = async { fetchScore() }
    println("${userDeferred.await()} scored ${scoreDeferred.await()}")
}

// Output:
// Alice scored 95

Key Takeaways

  • Coroutines are lightweight; many can run on just a few OS threads.
  • suspend fun marks a function that can pause and resume without blocking a thread.
  • launch is fire-and-forget; async returns a Deferred<T> retrieved with .await().
  • runBlocking bridges blocking code with coroutine code, mainly for main functions and tests.
  • Dispatchers (Main, IO, Default) control which thread pool a coroutine runs on.
  • Coroutines come from the kotlinx.coroutines library, not the core language.

Practice what you learned

Was this page helpful?

Topics covered

#Kotlin#KotlinProgrammingStudyNotes#Programming#CoroutinesInKotlin#Coroutines#Syntax#Explanation#Example#StudyNotes#SkillVeris