Coroutines — asosiy tushunchalar, Job va Dispatchers Kotlin da

Muallif: IT Sectr Nashr etilgan: 2026-03-16 O'qish vaqti: 8 daq

Coroutines (korutinlar) — kotlinx.coroutines kutubxonasi orqali mavjud bo'lgan asinxron dasturlash uchun Kotlin-ning yengil threadlaridir. JetBrains Kotlin Documentation, 2026 ma'lumotlariga ko'ra, Coroutines an'anaviy Thread-lardan farqli o'laroq, funksiya bajarilishini threadni bloklamasdan to'xtatish imkonini beradi. Korutinlar cheklangan thread hovuzida ishlaydi, bu esa ularni mahalliy threadlardan ming marta yengilroq qiladi. Kotlin Coroutines Android Jetpack, Retrofit, Room va Android ekotizimining boshqa mashhur kutubxonalari bilan to'liq integratsiyalangan.

Asosiy fikrlar

  • Coroutines — bloklanmasdan asinxron kod uchun Kotlin-ning yengil threadlari
  • suspend funksiyasi — threadni bloklamasdan to'xtab va qayta tiklana oladigan funksiya
  • Dispatcher korutinani bajarish uchun thread hovuzini belgilaydi
  • Job — bekor qilish va holatni kuzatish bilan korutin deskriptori
  • CoroutineScope korutinlarning hayot aylanishini va ularning tugashida bekor qilinishini boshqaradi

Kotlin korutinlari nima

Coroutines (korutinlar) — kotlinx.coroutines kutubxonasida amalga oshirilgan Kotlin-dagi asinxron dasturlash mexanizmidir. Operatsion tizim threadlaridan farqli o'laroq, korutinlar ma'lum bir threadga bog'liq emas: ular bir threadda to'xtab, boshqa threadda tiklanishi mumkin. Bitta thread minimal qo'shimcha xarajat bilan ular orasida almashinib, minglab korutinlarni bajarishi mumkin.

Korutinlar Kotlin 1.3 (2018) da eksperimental funksiya sifatida paydo bo'ldi va Kotlin 1.5 (2021) da barqaror bo'ldi. Coroutines callback hell muammosini async/await kabi hal qiladi, lekin boyroq API taqdim etadi: kanallar (Channel), Flow, Job ierarxiyasida istisnolarni boshqarish va Android Lifecycle bilan to'g'ridan-to'g'ri integratsiya.

JetBrains (2025) ma'lumotlariga ko'ra, har bir korutin mahalliy thread uchun 1+ MB ga nisbatan taxminan 100 bayt xotira sarflaydi. Bu OutOfMemoryError xavfisiz bitta ilovada millionlab korutinlarni ishga tushirish imkonini beradi. Aynan korutinlarning yengilligi ularni Android-da asinxronlik uchun afzal qilingan vositaga aylantiradi.

Korutinlar kapot ostida qanday ishlaydi

Har bir Kotlin korutini Continuation Passing Style (CPS) orqali state machine-ga kompilyatsiya qilinadi. Kompilyator har bir suspend funksiyasiga yashirin Continuation parametrini qo'shadi. Continuation tiklash nuqtasini va barcha mahalliy o'zgaruvchilarni o'z ichiga oladi. Korutin to'xtaganda, runtime Continuation-ni saqlaydi va tiklanganida uni Dispatcher hovuzidagi istalgan mavjud threadda tiklaydi.

Suspend funksiyalari: to'xtatish va tiklash

suspend — funksiyani to'xtatiladigan deb belgilovchi Kotlin kalit so'zidir. Bunday funksiya faqat boshqa suspend funksiyasidan yoki korutindan chaqirilishi mumkin. Suspend funksiyasi ichida boshqa suspend funksiyalari istalgan tartibda chaqirilishi mumkin va har bir chaqiruv nuqtasi potentsial to'xtash nuqtasidir.

Mexanika oddiy: suspend funksiyasi boshqa suspend funksiyasini chaqirganda, u threadni bo'shatib, shu nuqtada to'xtaydi. Chaqirilgan funksiya tugagandan so'ng, runtime saqlangan joydan bajarishni davom ettiradi. Bunga cooperative cancellation deyiladi — hech qanday thread bloklanmaydi.

  • To'xtatish — korutin threadni bloklamasdan bo'shatadi
  • Tiklash — korutin to'xtagan joydan davom etadi
  • Thread — korutin A threadda to'xtab, B threadda tiklanishi mumkin
  • Istisnolar — sinxron koddagi kabi try/catch orqali boshqariladi

Muhim: suspend funksiyasi sukut bo'yicha asinxron emas. Bajarish tartibi launch yoki async ishlatilmaguncha ketma-ket bo'lib qoladi. suspend faqat funksiyaning threadni bloklamasdan to'xtatilishiga va korutin kontekstining bir qismi bo'lishiga imkon beradi. Continuation Passing Style har bir suspend funksiyasi yashirin Continuation callback oladigan va kompilyator to'xtatishlar va tiklashlarni boshqarish uchun holat mashinasini yaratadigan kompilyatsiya modelidir.

CoroutineScope va Structured Concurrency

CoroutineScope — korutinlarning hayot aylanishini belgilovchi kontekstdir. Barcha korutinlar scope ichida ishga tushirilishi kerak. Scope bekor qilinganda (masalan, Activity tugaganda), uning barcha bola korutinlari avtomatik bekor qilinadi. Bu fon vazifalarining oqib ketishini oldini oladi. Android Jetpack har bir komponent uchun tayyor scopelarni taqdim etadi: ViewModel uchun viewModelScope va Activity va Fragment uchun lifecycleScope, tegishli komponent yo'q qilinganda avtomatik bekor qilinadi.

Structured Concurrency — korutin barcha bola korutinlari tugamaguncha tugamasligini kafolatlovchi prinsipdir. Job ierarxiyasi daraxt hosil qiladi: ildiz korutina parent job yaratadi, bolalar child jobs yaratadi. Parent job bekor qilinishi barcha bolalarga tarqaladi. Structured Concurrency korutinlar va threadlar o'rtasidagi asosiy farqdir.

ScopeQayerda ishlatiladiBekor qilish
GlobalScopeFaqat daemon vazifalar uchunAvtomatik bekor qilinmaydi
viewModelScopeAndroid ViewModelViewModel tozalanganda
lifecycleScopeAndroid Activity/FragmentLifecycle yo'q qilinganda
coroutineScopeSuspend funksiyasi ichidaParent job bekor qilinganda

Xatolarni boshqarish uchun SupervisorJob

Oddiy Job bitta bola korutinidagi xatoda barcha siblings-larni bekor qiladi. SupervisorJob — istisno: bitta bola korutinidagi nosozlik qolganlariga ta'sir qilmaydi. Bu bir nechta mustaqil vazifalar parallel bajarilayotganda va ulardan biri qolganlarini bekor qilishga hojat qoldirmasdan ishlamay qolishi mumkin bo'lganda muhimdir.

Dispatchers va korutin quruvchilari

Dispatchers korutinlar qaysi threadlarda bajarilishini aniqlaydi. Dispatchers.Main — Android-ning asosiy UI threadi. Dispatchers.IO — bloklovchi operatsiyalar (tarmoq, disk) uchun hovuz. Dispatchers.Default — CPU intensiv vazifalar uchun. Dispatchers.Unconfined — joriy threadda boshlanadi, lekin unda qolishini kafolatlamaydi. To'g'ri Dispatcher tanlash samaradorlik uchun muhim: Default-da IO vazifasi hisoblashlar uchun hovuzni bloklaydi, IO-da CPU vazifasi esa keraksiz threadlar yaratadi.

withContext — korutin ichida Dispatcher-ni almashtirish uchun funksiya. Masalan, JSON parse qiluvchi suspend funksiyasi hisoblash vaqtida Dispatchers.Default-ga o'tib, UI yangilash uchun Dispatchers.Main-ga qaytishi mumkin. withContext Android ishlanmasida eng ko'p ishlatiladigan quruvchidir.

Uch asosiy korutin quruvchisi

launch — korutinani ishga tushiradi, Job qaytaradi, natija qaytarmaydi (fire-and-forget). async — korutinani ishga tushiradi, natijani await orqali olish uchun Deferred qaytaradi. runBlocking — korutinani bajarish uchun joriy threadni bloklaydi (faqat testlar va main funksiyalar uchun). Quruvchi tanlash stsenariyga bog'liq: launch hodisalar va yangilanishlar uchun, async natija bilan vazifalar uchun, runBlocking faqat testlar yoki kirish nuqtalari uchun mos keladi.

Kotlin da korutinlar bilan kod namunalari

Uchta amaliy stsenariyni ko'rib chiqamiz: launch bilan asosiy korutin, async bilan parallel chaqiruv va SupervisorJob bilan xato boshqaruvi.

Korutinni launch bilan ishga tushirish

viewModelScope.launch ViewModel kontekstida korutinni ishga tushiradi. ViewModel tozalanganda korutin avtomatik bekor qilinadi.

kotlin
class ProfileViewModel : ViewModel() {
    fun loadUser() {
        viewModelScope.launch(Dispatchers.IO) {
            val user = api.fetchUser()
            withContext(Dispatchers.Main) {
                showUser(user)
            }
        }
    }
}

Async bilan parallel so'rovlar

coroutineScope async bilan uchta so'rovni parallel ishga tushiradi. Natijalar .await() orqali yig'iladi. Agar so'rovlardan biri ishlamay qolsa, hammasi bekor qilinadi.

kotlin
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 bilan xato boshqaruvi

SupervisorJob har bir korutinning mustaqil tugashiga imkon beradi. Bitta so'rovdagi xato qolganlarini bekor qilmaydi.

kotlin
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) }
}

Korutinlar vs threadlar: taqqoslash va stsenariylar

Threadlar — operatsion tizim primitividir. Har bir thread o'z stekiga (~1 MB) ega va yaratish va almashtirish uchun tizim chaqiruvini talab qiladi. Korutinlar — OS ga bog'liq bo'lmagan til primitividir. Ular holatni saqlash uchun Continuation dan foydalanadi va tizim chaqiruvlarisiz runtime darajasida almashtiriladi.

  • Xotira — thread ~1 MB, korutin ~100 bayt. 10 000 marta farq
  • Yaratish — thread ~1 µs syscall, korutin ~0.01 µs JVM darajasida
  • Almashtirish — thread ~0.1 µs (syscall), korutin ~0.001 µs (continuation)
  • Maksimum — minglab threadlar vs qurilmada millionlab korutinlar
  • Bekor qilish — thread tashqaridan bekor qilinmaydi (eskirgan Thread.stop), korutin Job.cancel() orqali bekor qilinishi mumkin

Google (2025) ma'lumotlariga ko'ra, korutinlarni threadlar o'rniga ishlatish Android ilovalarida fon vazifalari uchun xotira sarfini 90–95% ga kamaytiradi. Barcha zamonaviy Android kutubxonalari (Retrofit, Room, WorkManager) suspend funksiyalari orqali korutinlar uchun o'rnatilgan qo'llab-quvvatlashga ega. Ktor (JetBrains HTTP klient frameworki) ham to'liq korutinlar ustida qurilgan bo'lib, callback APisiz har bir so'rov uchun suspend-funksiyalar taqdim etadi. Room DAO da suspend-funksiyalar orqali korutinlarni qo'llab-quvvatlaydi, bu esa asosiy threadni bloklamasdan ma'lumotlar bazasi so'rovlarini bajarish imkonini beradi.

Qachon korutinlar o'rniga threadlarni ishlatish kerak

Threadlar JNI orqali mahalliy kod, vaqt cheklovisiz CPU intensiv bloklovchi chaqiruvlar (video render, simulyatsiyalar) va C kutubxonalari bilan integratsiya uchun zarur bo'lib qoladi. Qolgan hamma narsa uchun — korutinlar.

Tez-tez beriladigan savollar

Korutin threaddan nima bilan farq qiladi?

Korutin — mavjud threadda bajariladigan to'xtatiladigan ish birligidir. Thread o'z stekiga ega tizim resursidir. Korutinlar threadlardan minglab marta yengilroq va to'xtatilganda resurslarni bloklamaydi.

Dispatchers.IO nima va u Default dan nima bilan farq qiladi?

Dispatchers.IO bloklovchi I/O operatsiyalari (tarmoq, fayllar) uchun mo'ljallangan va kerak bo'lganda yangi threadlar yaratishi mumkin. Dispatchers.Default CPU intensiv hisoblashlar uchun qat'iy o'lchamdagi hovuzga ega (protsessor yadrolari soni).

Ishga tushirilgan korutinni qanday bekor qilish mumkin?

Job.cancel() korutinni va uning barcha bolalarini bekor qiladi. Korutin ichida bekor qilishni tekshirish uchun ensureActive() dan foydalaning — korutin bekor qilingan bo'lsa CancellationException tashlaydi.

Korutinlarni RxJava bilan ishlatish mumkinmi?

Ha — kotlinx-coroutines-rx3 kutubxonasi orqali. U Observable/Single ni suspend funksiyalariga va aksincha flowable orqali aylantirish uchun awaitSingle, awaitFirst va boshqa funksiyalarni taqdim etadi.

Korutinlarda Flow nima?

Flow — korutinlar uchun RxJava Observable analogi bo'lgan sovuq asinxron ma'lumot oqimidir. Flow qiymatlarni ketma-ket chiqaradi va istisno yoki muvaffaqiyat bilan tugaydi. Map, filter, catch va boshqa operatorlarni qo'llab-quvvatlaydi.

Xulosa

  • Coroutines — Continuation Passing Style orqali bloklanmasdan to'xtash bilan Kotlin-ning yengil threadlari
  • suspend — to'xtatiladigan funksiyalarni belgilash uchun kalit so'z
  • Dispatchers thread hovuzini boshqaradi: Main, IO, Default mos ravishda
  • CoroutineScope korutinlarning hayot aylanishini komponentga bog'laydi (Activity, ViewModel)
  • launch korutinni natijasiz ishga tushiradi, async/await — natija bilan
  • Structured Concurrency bola korutinlarning ierarxik bekor qilinishini kafolatlaydi
  • Korutinlar vs threadlar — korutinlar 10 000 marta yengilroq va Android uchun standartdir

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing