Dispatchers — asosiy tushunchalar, dispetcher turlari va ularning ishlashi

Muallif: IT Sectr Nashr etilgan: 2026-06-22 O'qish vaqti: 9 daq

Dispatchers Kotlin Coroutines-da — CoroutineContext komponentlari bo'lib, korutinlarni bajarish uchun iplarni (thread) aniqlaydi: Main (UI-thread), IO (tarmoq va disk), Default (CPU-intensiv vazifalar) va Unconfined (joriy thread). Har bir dispetcher muayyan ish turi uchun optimallashtirilgan ixtisoslashgan thread hovuzini boshqaradi. JetBrains, 2024 qo'llanmasiga ko'ra, to'g'ri dispetcherni tanlash ilovaning ishlashi va barqarorligi uchun juda muhimdir.

Asosiy fikrlar

  • Dispatchers — vazifalarni iplar bo'ylab taqsimlashni boshqaradigan oldindan belgilangan korutin dispetcherlari
  • Dispatchers.Main — Android UI-thread, interfeysni yangilash va View bilan ishlash uchun
  • Dispatchers.IO — tarmoq so'rovlari, fayllarni o'qish/yozish va ma'lumotlar bazasi uchun hovuz (64 tagacha thread)
  • Dispatchers.Default — protsessor yadrolari soniga qarab CPU-intensiv vazifalar uchun hovuz
  • Dispatchers.Unconfined — o'zgartirishsiz, joriy threadni meros qilib olish

Dispatchers nima?

Dispatchers — CoroutineDispatcher interfeysining implementatsiyalari bo'lib, CoroutineContext elementlaridir. Ular korutina qaysi thread yoki thread hovuzida bajarilishini aniqlaydi. launch yoki async orqali korutina yaratilganda dispetcher birinchi parametr sifatida uzatilishi mumkin: launch(Dispatchers.IO) { ... }. Agar dispetcher ko'rsatilmagan bo'lsa, tashqi CoroutineScope-dan meros qilib olinadi.

Kotlin to'rtta o'rnatilgan dispetcherni taqdim etadi: Main, IO, Default, Unconfined. Har bir dispetcher muayyan operatsiya turi uchun optimallashtirilgan o'z thread hovuzidan foydalanadi. To'g'ri dispetcherni tanlash ilovaning ishlashini belgilaydi: noto'g'ri tanlov interfeys kechikishlariga, CPU yadrolarining bo'sh turishiga yoki threadlarning samarasiz sarflanishiga olib keladi.

DispetcherThread hovuziMaks. threadQo'llanilishi
Dispatchers.MainBitta (UI)1UI yangilash, LiveData, View
Dispatchers.IOIO hovuzi64 (limitedParallelism)Tarmoq, fayllar, ma'lumotlar bazasi
Dispatchers.DefaultCPU hovuziN yadroSaralash, parsering, hisoblashlar
Dispatchers.UnconfinedJoriy threadYo'qOraliq operatsiyalar, testlar

Dispatchers.Main: UI-thread

Dispatchers.Main — korutinalarni Android asosiy threadida bajaradigan dispetcher. Interfeys bilan bog'liq operatsiyalar uchun mo'ljallangan: TextView yangilash, notifyDataSetChanged chaqiruvi, LiveData va StateFlow bilan ishlash. Android-da bu dispetcher Handler (Looper.getMainLooper()) orqali implementatsiya qilingan.

kotlin
// UI yangilanishlari uchun Main-ga to'g'ri o'tish
viewModelScope.launch(Dispatchers.IO) {
    val data = repository.fetchData()
    withContext(Dispatchers.Main) {
        _uiState.value = data
    }
}

Agar korutina allaqachon Main-dispetcherida bo'lsa, qo'shimcha withContext(Dispatchers.Main) qo'shimcha yuk yaratmaydi — dispetcher joriy threadni tekshiradi va o'tishni o'tkazib yuboradi. withContext dispetcherlar o'rtasida o'tishning afzal ko'rilgan usulidir.

Dispatchers.IO: tarmoq va disk operatsiyalari

Dispatchers.IO — kirish-chiqish operatsiyalari uchun optimallashtirilgan dispetcher: HTTP so'rovlari (Ktor, OkHttp), fayllarni o'qish va yozish, Room yoki SQLDelight bilan ishlash. U sukut bo'yicha 64 thread dan iborat hovuzdan foydalanadi, yuk ostida masshtablanadi. Har bir yangi IO so'rovi limitga yetguncha qo'shimcha thread yaratishi mumkin.

Parallellikni cheklash

Bir vaqtda IO operatsiyalari sonini nazorat qilish uchun limitedParallelism() dan foydalaning. Bu funksiya parallel threadlar sonini cheklovchi yangi dispetcher yaratadi, ommaviy operatsiyalarda hovuzning tugashining oldini oladi.

kotlin
val limitedIo = Dispatchers.IO.limitedParallelism(4)

// 4 ta parallel operatsiya cheklovi bilan 100 ta faylni yuklash
coroutineScope {
    val files = (1..100).map { index ->
        async(limitedIo) {
            downloadFile("file_$index")
        }
    }
    files.awaitAll()
}

Korutina kutish vaqtini o'tkazadigan barcha operatsiyalar (I/O-bound) uchun IO-dispetcheridan foydalaning. IO-dispetcherida CPU-intensiv vazifalar samarasiz — ular kirish-chiqish uchun mo'ljallangan threadlarni egallab, tizimning o'tkazish qobiliyatini pasaytiradi.

Dispatchers.Default: CPU-intensiv vazifalar

Dispatchers.Default — protsessorni yuklaydigan hisoblash operatsiyalari uchun dispetcher: saralash, filtrlash, JSON parseringi (Moshi, Kotlinx Serialization), tasvirlarni qayta ishlash, hisoblashlar. Hovuz hajmi protsessor yadrolari soniga teng (lekin 2 dan kam emas). Bu kontekst almashinuvisiz CPU ning maksimal yuklanishini ta'minlaydi.

kotlin
suspend fun processData(input: List<RawRecord>): List<ProcessedRecord> {
    return withContext(Dispatchers.Default) {
        input
            .parallelStream()
            .map { transform(it) }
            .toList()
    }
}

IO operatsiyalari uchun Dispatchers.Default dan foydalanmang — bu hisoblash vazifalarini qayta ishlay oladigan CPU hovuzi threadlarini bloklaydi. IO va Default ga bo'lish tizim resurslaridan optimal foydalanish imkonini beradi: IO threadlari kirish-chiqishni kutadi, CPU threadlari doim hisoblashlar bilan band.

Dispatchers.Unconfined: joriy thread

Dispatchers.Unconfined — korutinani hech qanday hovuzga bog'lamaydigan maxsus dispetcher. Korutina launch/async chaqirilgan threadda bajarishni boshlaydi va to'xtatilgandan so'ng resume chaqirgan threadda davom etadi. Bu xatti-harakat qat'iy kontekst talab qilmaydigan oraliq operatsiyalar uchun mos keladi.

kotlin
fun main() = runBlocking {
    launch(Dispatchers.Unconfined) {
        println("Kechikishdan oldin: ${Thread.currentThread().getName()}")
        delay(500L)
        println("Kechikishdan keyin: ${Thread.currentThread().getName()}")
    }
}

Production kodda Dispatchers.Unconfined kamdan-kam qo'llaniladi. Asosiy holatlar: ma'lumotlarni boshqa dispetcherga o'tkazishdan oldin engil transformatsiyalar va testlar. Production yuki uchun aniq dispetcherlardan foydalaning — Unconfined oldindan aytib bo'lmaydi, chunki bajarish threadi resume implementatsiyasiga bog'liq.

Dispetcher qanday tanlanadi

Dispetcher tanlash vazifa turiga qarab belgilanadi: UI operatsiyalari → Main, I/O-bound → IO, CPU-bound → Default, oraliq → scope-dan meros. Android uchun korutinani asosiy ish bajariladigan dispetcherda ishga tushirish va UI yangilashdan oldin withContext orqali Main-ga o'tish tavsiya etiladi.

  • IO operatsiyalarini Main-dispetcherida ishga tushirmang — bu UI-ni bloklaydi
  • CPU-intensiv vazifalarni IO-dispetcherida ishga tushirmang — bu IO hovuzi threadlarini samarasiz sarflaydi
  • limitedParallelism dan foydalaning ommaviy IO operatsiyalarida parallellikni nazorat qilish uchun
  • Dispetcher ni o'zgartiring withContext bilan, yangi scope yaratish orqali emas
  • Dispetcher ni scope-dan meros qilib oling korutina maxsus hovuz talab qilmasa

Murakkab stsenariylar uchun dispetcherlarni + operatori bilan birlashtiring: Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler. Bu belgilangan dispetcher, xato boshqaruvi va izolyatsiya qilingan Job iyerarxiyasi bilan CoroutineContext yaratadi.

Tez-tez beriladigan savollar

Dispatchers.IO va Dispatchers.Default nimasi bilan farq qiladi?

Dispatchers.IO I/O-bound operatsiyalari (kirish-chiqish kutish) uchun 64 tagacha thread hovuzidan foydalanadi, Dispatchers.Default esa hisoblash vazifalari uchun CPU yadrolari soniga qarab hovuzdan. Thread yetishmaganda ikkala hovuz bir-biri bilan threadlarni ulashishi mumkin.

Kotlin Coroutines-da o'z dispetcherimni yaratish mumkinmi?

Ha, bitta threadli uchun newSingleThreadContext() yoki sobit hovuz uchun newFixedThreadPoolContext() dan foydalaning. Production uchun mavjud dispetcherlar asosida limitedParallelism() qo'llang — bu yangi hovuzlar yaratishdan ko'ra samaraliroq.

Fon threadida Dispatchers.Main chaqirilsa nima bo'ladi?

Dispatchers.Main mavjud bo'lmasa (masalan, JUnit testida yoki fon xizmatida), IllegalStateException tashlanadi. Testlar uchun TestCoroutineDispatcher, fon xizmatlari uchun Dispatchers.IO yoki Default dan foydalaning.

Parallel IO operatsiyalari sonini qanday cheklash mumkin?

Dispatchers.IO.limitedParallelism(N) dan foydalaning, bu yerda N — maksimal parallel threadlar soni. Bu ommaviy so'rovlarda hovuzning tugashini oldini oladi va boshqariladigan parallellikni ta'minlaydi.

Dispatchers.Unconfined qachon ishlatilishi kerak?

Dispatchers.Unconfined oraliq operatsiyalar uchun mos keladi: ma'lumotlarni boshqa dispetcherga o'tkazishdan oldin engil transformatsiyalar, test stsenariylari. Android production kodida to'xtatilgandan keyin bajarish threadi noaniq bo'lgani uchun tavsiya etilmaydi.

Xulosa

  • Dispatchers — korutinlarning bajarish threadlarini aniqlaydigan CoroutineContext komponentlari
  • Dispatchers.Main — Android UI operatsiyalari uchun, bitta asosiy thread
  • Dispatchers.IO — tarmoq va disk operatsiyalari uchun, 64 tagacha thread hovuzi
  • Dispatchers.Default — CPU-intensiv hisoblashlar uchun, yadrolar soniga qarab hovuz
  • Dispatchers.Unconfined — threadga bog'lanmagan, oraliq operatsiyalar uchun
  • withContext — korutina ichida dispetcherlar o'rtasida o'tishning asosiy mexanizmi
  • Noto'g'ri dispetcher tanlovi UI kechikishlariga yoki resurslarning samarasiz ishlatilishiga olib keladi

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