Panduan Coroutines di kotlinlang.org/docs/coroutines-overview.html adalah sumber otoritatif untuk pemrograman asinkron di Kotlin. Coroutines menawarkan cara menulis kode asinkron yang terlihat seperti kode biasa — tidak ada callback hell, tidak ada Promise.then. Pada chapter ini kita memetakan topik utama panduan, mendemokan suspend function, async/await paralel, dan Flow sederhana, lalu membandingkan coroutine dengan thread tradisional.

Konsep Inti Coroutines #

Panduan resmi menyusun konsep coroutine dalam beberapa blok bangunan. Berikut ringkasan singkat:

KonsepPeran
suspend funFungsi yang bisa pause/resume tanpa blocking thread
CoroutineScopeKonteks untuk launch/async; pembatalan menyebar
DispatcherMain (UI), IO (file/network), Default (CPU-bound)
JobHandle untuk membatalkan dan menunggu coroutine
Deferred<T>Future yang bisa di-await (hasil dari async)
Flow<T>Cold stream nilai asinkron, mirip Observable RxJava

Demo suspend, async, dan Flow #

Cuplikan berikut memadukan tiga konsep utama: suspend function dengan delay, paralel async/await, dan Flow sederhana. Karena file ini membutuhkan library kotlinx-coroutines-core, kompilasi memerlukan classpath tambahan:

kotlin
// panduan_coroutines.kt
// Tour singkat Panduan Coroutines (https://kotlinlang.org/docs/coroutines-overview.html)
// Demo: coroutine dasar dengan runBlocking, async/await, dan Flow sederhana.
//
// File ini membutuhkan library kotlinx-coroutines-core di classpath.
// Compile: kotlinc -cp "/home/z/my-project/kotlin_libs/*" ...

import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking

suspend fun ambilData(id: Int): String {
    delay(100)  // simulasi IO
    return "data-$id"
}

fun hitungFlow(): Flow<Int> = flow {
    for (i in 1..3) {
        delay(50)
        emit(i)
    }
}

fun main() = runBlocking {
    println("=== Panduan Coroutines ===")
    println("Sumber: https://kotlinlang.org/docs/coroutines-overview.html")
    println()

    println("--- 1. suspend function ---")
    val data = ambilData(1)
    println("ambilData(1) = $data")

    println()
    println("--- 2. async / await paralel ---")
    coroutineScope {
        val a = async { ambilData(1) }
        val b = async { ambilData(2) }
        val c = async { ambilData(3) }
        val hasil = listOf(a.await(), b.await(), c.await())
        println("Hasil paralel: $hasil")
    }

    println()
    println("--- 3. Flow sederhana ---")
    val list = hitungFlow().toList()
    println("Flow.toList() = $list")

    println()
    println("--- 4. Konsep utama coroutines ---")
    val konsep = listOf(
        "suspend function -> fungsi yang bisa pause/resume tanpa blocking thread",
        "CoroutineScope   -> konteks untuk launch/async; cancel menyebar",
        "Dispatcher        -> Main (UI), IO (file/network), Default (CPU)",
        "Job              -> handle untuk cancel dan join",
        "Deferred<T>      -> future (Promise) yang bisa di-await",
        "Flow<T>          -> stream cold; values di-emit saat dikoleksi"
    )
    konsep.forEach { println("  $it") }

    println()
    println("--- 5. Perbandingan dengan Thread ---")
    val perbandingan = listOf(
        "Thread berat (~1MB stack), coroutine ringan (~100 byte)",
        "Thread diblokir tidak bisa dipakai, coroutine bisa suspend",
        "Thread tidak bisa dibatalkan dengan aman, coroutine bisa di-cancel",
        "Thread butuh sinkronisasi manual, coroutine punya structured concurrency"
    )
    perbandingan.forEach { println("  $it") }

    println()
    println("--- 6. Topik panduan coroutines ---")
    val topik = listOf(
        "Coroutines basics        -> launch, delay, runBlocking",
        "Cancellation             -> cancel() dan CoroutineScope",
        "Timeouts                 -> withTimeout { }",
        "Composing suspending     -> async, awaitAll",
        "Coroutine context        -> Dispatchers, Job, CoroutineExceptionHandler",
        "Flow                     -> cold stream, operator, exception",
        "Channels                 -> hot stream untuk komunikasi antar coroutine"
    )
    topik.forEach { println("  $it") }
}

Output yang Dihasilkan:

text
=== Panduan Coroutines ===
Sumber: https://kotlinlang.org/docs/coroutines-overview.html

--- 1. suspend function ---
ambilData(1) = data-1

--- 2. async / await paralel ---
Hasil paralel: [data-1, data-2, data-3]

--- 3. Flow sederhana ---
Flow.toList() = [1, 2, 3]

--- 4. Konsep utama coroutines ---
  suspend function -> fungsi yang bisa pause/resume tanpa blocking thread
  CoroutineScope   -> konteks untuk launch/async; cancel menyebar
  Dispatcher        -> Main (UI), IO (file/network), Default (CPU)
  Job              -> handle untuk cancel dan join
  Deferred<T>      -> future (Promise) yang bisa di-await
  Flow<T>          -> stream cold; values di-emit saat dikoleksi

--- 5. Perbandingan dengan Thread ---
  Thread berat (~1MB stack), coroutine ringan (~100 byte)
  Thread diblokir tidak bisa dipakai, coroutine bisa suspend
  Thread tidak bisa dibatalkan dengan aman, coroutine bisa di-cancel
  Thread butuh sinkronisasi manual, coroutine punya structured concurrency

--- 6. Topik panduan coroutines ---
  Coroutines basics        -> launch, delay, runBlocking
  Cancellation             -> cancel() dan CoroutineScope
  Timeouts                 -> withTimeout { }
  Composing suspending     -> async, awaitAll
  Coroutine context        -> Dispatchers, Job, CoroutineExceptionHandler
  Flow                     -> cold stream, operator, exception
  Channels                 -> hot stream untuk komunikasi antar coroutine

Perhatikan urutan output: pemanggilan ambilData(1) selesai dalam 100 ms, lalu tiga async dijalankan paralel dan selesai kira-kira 100 ms (bukan 300 ms), karena coroutine ketiganya berjalan konkuren. Flow mengeluarkan tiga nilai dengan jeda 50 ms masing-masing.

Coroutines vs Thread #

Panduan resmi sering membandingkan coroutine dengan thread. Thread JVM berat: setiap thread mengalokasikan sekitar 1 MB stack, sehingga 10.000 thread akan menghabiskan 10 GB memori. Coroutine ringan: setiap coroutine hanya memakai sekitar 100 byte, sehingga jutaan coroutine bisa berjalan paralel dalam satu proses. Lebih jauh, thread tidak bisa dibatalkan dengan aman — Thread.interrupt() hanya menandai flag dan target bebas mengabaikannya. Coroutine mendukung structured concurrency: pembatalan scope otomatis membatalkan semua coroutine anak.

Referensi Lanjutan #

  • Coroutines overview — halaman resmi panduan coroutines Kotlin mencakup suspend, launch, async, dan dispatchers

Selanjutnya #

Coroutines adalah satu pilar ekosistem Kotlin. Pilar berikutnya adalah kemampuan menulis satu kode untuk beberapa target sekaligus. Chapter berikutnya membahas panduan Kotlin Multiplatform — strategi expect/actual dan struktur source set lintas platform.