Coroutines (korutin) adalah thread ringan Kotlin untuk pemrograman asinkron, tersedia melalui pustaka kotlinx.coroutines. Menurut JetBrains Kotlin Documentation, 2026, Coroutines memungkinkan penangguhan eksekusi fungsi tanpa memblokir thread, berbeda dengan Thread tradisional. Korutin berjalan pada kumpulan thread terbatas, membuatnya ribuan kali lebih ringan daripada thread native. Coroutines Kotlin terintegrasi penuh dengan Android Jetpack, Retrofit, Room, dan pustaka populer lainnya di ekosistem Android.
Poin Utama
Coroutines (korutin) adalah mekanisme pemrograman asinkron di Kotlin, diimplementasikan dalam pustaka kotlinx.coroutines. Berbeda dengan thread sistem operasi, korutin tidak terikat pada thread tertentu: mereka dapat ditangguhkan di satu thread dan dilanjutkan di thread lain. Satu thread dapat menjalankan ribuan korutin, beralih di antara mereka dengan overhead minimal.
Korutin muncul di Kotlin 1.3 (2018) sebagai fitur eksperimental dan menjadi stabil di Kotlin 1.5 (2021). Coroutines memecahkan masalah callback hell mirip dengan async/await, tetapi menawarkan API yang lebih kaya: saluran (Channel), Flow, penanganan pengecualian dalam hierarki Job, dan integrasi langsung dengan Android Lifecycle.
Menurut JetBrains (2025), setiap korutin mengonsumsi sekitar 100 byte memori dibandingkan 1+ MB untuk thread native. Ini memungkinkan menjalankan jutaan korutin dalam satu aplikasi tanpa risiko OutOfMemoryError. Justru ringannya korutin menjadikannya alat pilihan untuk asinkronisitas di Android.
Setiap korutin Kotlin dikompilasi menjadi state machine melalui Continuation Passing Style (CPS). Kompiler menambahkan parameter tersembunyi Continuation ke setiap fungsi suspend. Continuation berisi titik kelanjutan dan semua variabel lokal. Saat korutin ditangguhkan, runtime menyimpan Continuation, dan saat dilanjutkan, runtime memulihkannya di thread yang tersedia dari kumpulan Dispatcher.
suspend — kata kunci Kotlin yang menandai fungsi sebagai dapat ditangguhkan. Fungsi semacam itu hanya dapat dipanggil dari fungsi suspend lain atau dari korutin. Di dalam fungsi suspend, fungsi suspend lain dapat dipanggil dalam urutan apa pun, dan setiap titik panggilan adalah potensi titik penangguhan.
Mekanismenya sederhana: ketika fungsi suspend memanggil fungsi suspend lain, fungsi tersebut menangguhkan di titik itu, membebaskan thread. Setelah fungsi yang dipanggil selesai, runtime melanjutkan eksekusi dari lokasi yang disimpan. Ini disebut cooperative cancellation — tidak ada thread yang diblokir.
Penting: fungsi suspend tidak asinkron secara default. Urutan eksekusi tetap sekuensial jika launch atau async tidak digunakan. suspend hanya memungkinkan fungsi untuk ditangguhkan tanpa memblokir thread dan menjadi bagian dari konteks korutin. Continuation Passing Style adalah model kompilasi di mana setiap fungsi suspend menerima callback tersembunyi Continuation, dan kompiler menghasilkan mesin status untuk mengelola penangguhan dan kelanjutan.
CoroutineScope adalah konteks yang menentukan siklus hidup korutin. Semua korutin harus dijalankan di dalam scope. Ketika scope dibatalkan (misalnya, saat Activity berakhir), semua korutin anaknya secara otomatis dibatalkan. Ini mencegah kebocoran tugas latar belakang. Android Jetpack menyediakan scope siap pakai untuk setiap komponen: viewModelScope untuk ViewModel dan lifecycleScope untuk Activity dan Fragment, yang secara otomatis dibatalkan saat komponen terkait dihancurkan.
Structured Concurrency — prinsip yang menjamin bahwa korutin tidak akan selesai sampai semua korutin anaknya selesai. Hierarki Job membentuk pohon: korutin akar membuat parent job, anak-anak membuat child jobs. Pembatalan parent job menyebar ke semua anak. Structured Concurrency adalah perbedaan fundamental antara korutin dan thread.
| Scope | Di mana digunakan | Pembatalan |
|---|---|---|
| GlobalScope | Hanya untuk tugas daemon | Tidak dibatalkan otomatis |
| viewModelScope | Android ViewModel | Saat ViewModel dibersihkan |
| lifecycleScope | Android Activity/Fragment | Saat lifecycle dihancurkan |
| coroutineScope | Di dalam fungsi suspend | Saat parent job dibatalkan |
Job biasa saat terjadi kesalahan pada satu korutin anak akan membatalkan semua siblings. SupervisorJob adalah pengecualian: kegagalan pada satu korutin anak tidak memengaruhi yang lain. Ini penting ketika beberapa tugas independen dijalankan secara paralel dan salah satunya mungkin gagal tanpa perlu membatalkan yang lain.
Dispatchers menentukan pada thread mana korutin dijalankan. Dispatchers.Main — thread UI utama Android. Dispatchers.IO — kumpulan untuk operasi pemblokiran (jaringan, disk). Dispatchers.Default — untuk tugas CPU-intensif. Dispatchers.Unconfined — mulai di thread saat ini tetapi tidak menjamin tetap di sana. Memilih Dispatcher yang tepat sangat penting untuk kinerja: tugas IO di Default akan memblokir kumpulan untuk komputasi, sementara tugas CPU di IO akan membuat thread yang tidak perlu.
withContext — fungsi untuk mengganti Dispatcher di dalam korutin. Misalnya, fungsi suspend yang mem-parsing JSON dapat beralih ke Dispatchers.Default selama komputasi dan kembali ke Dispatchers.Main untuk memperbarui UI. withContext adalah pembangun yang paling sering digunakan dalam pengembangan Android.
launch — menjalankan korutin, mengembalikan Job, tidak mengembalikan hasil (fire-and-forget). async — menjalankan korutin, mengembalikan Deferred dari mana hasil dapat diperoleh melalui await. runBlocking — memblokir thread saat ini untuk menjalankan korutin (hanya untuk pengujian dan fungsi main). Pemilihan pembangun tergantung pada skenario: launch cocok untuk peristiwa dan pembaruan, async — untuk tugas dengan hasil, runBlocking — hanya untuk pengujian atau titik masuk.
Mari kita lihat tiga skenario praktis: korutin dasar dengan launch, panggilan paralel dengan async, dan penanganan kesalahan dengan SupervisorJob.
viewModelScope.launch menjalankan korutin dalam konteks ViewModel. Saat ViewModel dibersihkan, korutin secara otomatis dibatalkan.
class ProfileViewModel : ViewModel() {
fun loadUser() {
viewModelScope.launch(Dispatchers.IO) {
val user = api.fetchUser()
withContext(Dispatchers.Main) {
showUser(user)
}
}
}
}
coroutineScope dengan async menjalankan tiga permintaan secara paralel. Hasil dikumpulkan melalui .await(). Jika salah satu permintaan gagal, semua dibatalkan.
suspend fun loadDashboard(): Dashboard = coroutineScope {
val user = async { api.fetchUser() }
val posts = async { api.fetchPosts() }
val stats = async { api.fetchStats() }
Dashboard(user.await(), posts.await(), stats.await())
}
SupervisorJob memungkinkan setiap korutin selesai secara independen. Kesalahan dalam satu permintaan tidak membatalkan yang lain.
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
try { api.fetchUsers() } catch (e: Exception) { log(e) }
}
scope.launch {
try { api.fetchPosts() } catch (e: Exception) { log(e) }
}
Thread — primitif sistem operasi. Setiap thread memiliki stack sendiri (~1 MB) dan memerlukan panggilan sistem untuk pembuatan dan peralihan. Korutin — primitif bahasa, tidak terikat pada OS. Mereka menggunakan Continuation untuk menyimpan status dan beralih di tingkat runtime tanpa panggilan sistem.
Menurut Google (2025), penggunaan korutin alih-alih thread mengurangi konsumsi memori untuk tugas latar belakang di aplikasi Android sebesar 90–95%. Semua pustaka Android modern (Retrofit, Room, WorkManager) memiliki dukungan bawaan untuk korutin melalui fungsi suspend. Ktor (kerangka kerja HTTP klien JetBrains) juga sepenuhnya dibangun di atas korutin, menyediakan fungsi-suspend untuk setiap permintaan tanpa API callback. Room mendukung korutin melalui fungsi-suspend di DAO, memungkinkan eksekusi kueri database tanpa memblokir thread utama.
Thread tetap diperlukan untuk kode native melalui JNI, panggilan pemblokiran CPU-intensif tanpa batas waktu (rendering video, simulasi), dan saat integrasi dengan pustaka C. Untuk yang lainnya — korutin.
Pertanyaan yang Sering Diajukan
Korutin — unit kerja yang dapat ditangguhkan yang berjalan di thread yang ada. Thread adalah sumber daya sistem dengan stack sendiri. Korutin ribuan kali lebih ringan daripada thread dan tidak memblokir sumber daya saat ditangguhkan.
Dispatchers.IO ditujukan untuk operasi I/O pemblokiran (jaringan, file) dan dapat membuat thread baru jika diperlukan. Dispatchers.Default memiliki kumpulan ukuran tetap (jumlah inti CPU) untuk komputasi CPU-intensif.
Job.cancel() membatalkan korutin dan semua anaknya. Untuk memeriksa pembatalan di dalam korutin, gunakan ensureActive() — ia melempar CancellationException jika korutin dibatalkan.
Ya — melalui pustaka kotlinx-coroutines-rx3. Pustaka ini menyediakan fungsi awaitSingle, awaitFirst, dan lainnya untuk mengonversi Observable/Single menjadi fungsi suspend dan sebaliknya melalui flowable.
Flow — aliran data asinkron dingin, analog RxJava Observable untuk korutin. Flow memancarkan nilai secara berurutan dan berakhir dengan pengecualian atau keberhasilan. Mendukung operator map, filter, catch, dan lainnya.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga