</>
Skip to content
Kotlin lessons (32/33)

Kotlin — Coroutines

Basic coroutine

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000)
        println("World!")
    }
    println("Hello,")
    delay(1000)
}
// Output: Hello, World!

Launch and async

import kotlinx.coroutines.*

fun main() = runBlocking {
    // launch: fire and forget
    launch {
        delay(1000)
        println("Task 1 done")
    }

    // async: returns a result
    val deferred = async {
        delay(500)
        42
    }

    println("Result: ${deferred.await()}") // 42
}

Dispatchers

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch(Dispatchers.Default) {
        println("Default: ${Thread.currentThread().name}")
    }

    launch(Dispatchers.IO) {
        println("IO: ${Thread.currentThread().name}")
    }

    launch(Dispatchers.Unconfined) {
        println("Unconfined: ${Thread.currentThread().name}")
    }
}

Structured concurrency

import kotlinx.coroutines.*

suspend fun fetchData(): String {
    delay(1000)
    return "Data from API"
}

fun main() = runBlocking {
    val data = fetchData()
    println(data)
}

Exception handling

import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Caught: ${exception.message}")
    }

    launch(handler) {
        throw RuntimeException("Something went wrong")
    }

    delay(1000)
}

Channel basics

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

fun main() = runBlocking {
    val channel = Channel<Int>()

    launch {
        for (i in 1..5) {
            channel.send(i)
        }
        channel.close()
    }

    for (value in channel) {
        println(value)
    }
}

Best practices

  • Use runBlocking only in main functions
  • Use launch for fire-and-forget tasks
  • Use async when you need a result
  • Prefer structured concurrency over GlobalScope
  • Handle exceptions with CoroutineExceptionHandler

Mini Practice

Write Kotlin code that:

  1. Launches two coroutines that run concurrently
  2. Uses async and await to get results
  3. Handles exceptions with a CoroutineExceptionHandler
  4. Sends and receives on a Channel

Up Next

Congratulations! You've completed the Kotlin fundamentals. Continue exploring advanced topics like flows, serialization, and multiplatform development.

Related Topics

Frequently Asked Questions about Coroutines

What is Coroutines in Kotlin?

Coroutines is a fundamental concept in Kotlin. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn Coroutines?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Coroutines.

Why is Coroutines important in Kotlin?

Coroutines is essential for Kotlin development. Understanding this concept will help you write better code and solve real-world problems more effectively.