Dispatchers — temel kavramlar, dağıtıcı türleri ve nasıl çalıştıkları

Yazar: IT Sectr Yayınlanma: 2026-06-22 Okuma süresi: 9 dk

Dispatchers, Kotlin Coroutines'de CoroutineContext bileşenleridir ve coroutine'lerin yürütüleceği iş parçacıklarını belirler: Main (UI iş parçacığı), IO (ağ ve disk), Default (CPU yoğun görevler) ve Unconfined (mevcut iş parçacığı). Her dağıtıcı, belirli bir çalışma türü için optimize edilmiş uzmanlaşmış bir iş parçacığı havuzunu yönetir. JetBrains rehberi, 2024'e göre, doğru dağıtıcıyı seçmek uygulama performansı ve kararlılığı için kritiktir.

Önemli Noktalar

  • Dispatchers — görevlerin iş parçacıkları arasında dağıtımını yöneten önceden tanımlanmış coroutine dağıtıcıları
  • Dispatchers.Main — Android UI iş parçacığı, arayüzü güncellemek ve View ile çalışmak için
  • Dispatchers.IO — ağ istekleri, dosya okuma/yazma ve DB için havuz (64 iş parçacığına kadar)
  • Dispatchers.Default — işlemci çekirdeği sayısına göre CPU yoğun görevler için havuz
  • Dispatchers.Unconfined — geçerli iş parçacığını devralır, değiştirme olmaz

Dispatchers Nedir?

Dispatchers, CoroutineDispatcher arayüzünün uygulamalarıdır ve CoroutineContext'in öğeleridir. Coroutine'in hangi iş parçacığında veya iş parçacığı havuzunda yürütüleceğini belirlerler. launch veya async aracılığıyla bir coroutine oluştururken, dağıtıcı ilk parametre olarak iletilebilir: launch(Dispatchers.IO) { ... }. Hiçbir dağıtıcı belirtilmezse, dış CoroutineScope'tan devralınır.

Kotlin dört yerleşik dağıtıcı sağlar: Main, IO, Default, Unconfined. Her dağıtıcı, belirli bir işlem türü için optimize edilmiş kendi iş parçacığı havuzunu kullanır. Doğru dağıtıcıyı seçmek uygulama performansını belirler: yanlış seçim UI gecikmelerine, boşta CPU çekirdeklerine veya verimsiz iş parçacığı kullanımına yol açar.

Dağıtıcıİş Parçacığı HavuzuMaks. İş ParçacığıKullanım
Dispatchers.MainBir (UI)1UI güncellemeleri, LiveData, View
Dispatchers.IOIO havuzu64 (limitedParallelism)Ağ, dosyalar, DB
Dispatchers.DefaultCPU havuzuN çekirdekSıralama, ayrıştırma, hesaplamalar
Dispatchers.UnconfinedGeçerli iş parçacığıYokAra işlemler, testler

Dispatchers.Main: UI İş Parçacığı

Dispatchers.Main, coroutine'leri Android ana iş parçacığında yürüten dağıtıcıdır. UI ile ilgili işlemler için tasarlanmıştır: TextView güncelleme, notifyDataSetChanged çağırma, LiveData ve StateFlow ile çalışma. Android'de bu dağıtıcı, Handler (Looper.getMainLooper()) aracılığıyla uygulanır.

kotlin
// Correct switch to Main for UI updates
viewModelScope.launch(Dispatchers.IO) {
    val data = repository.fetchData()
    withContext(Dispatchers.Main) {
        _uiState.value = data
    }
}

Bir coroutine zaten Main dağıtıcısındaysa, ek withContext(Dispatchers.Main) ek yük oluşturmaz — dağıtıcı geçerli iş parçacığını kontrol eder ve değiştirmeyi atlar. withContext, dağıtıcılar arasında geçiş yapmanın tercih edilen yoludur.

Dispatchers.IO: Ağ ve Disk İşlemleri

Dispatchers.IO, G/Ç işlemleri için optimize edilmiş bir dağıtıcıdır: HTTP istekleri (Ktor, OkHttp), dosya okuma ve yazma, Room veya SQLDelight ile çalışma. Varsayılan olarak 64 iş parçacığından oluşan bir havuz kullanır, yük altında ölçeklenebilir. Her yeni G/Ç isteği, sınıra ulaşılana kadar ek bir iş parçacığı oluşturabilir.

Paralelliği Sınırlama

Eşzamanlı G/Ç işlemlerinin sayısını kontrol etmek için limitedParallelism() kullanın. Bu işlev, paralel iş parçacığı sayısında bir sınırla yeni bir dağıtıcı oluşturarak toplu işlemler sırasında havuzun tükenmesini önler.

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

// Load 100 files with limit of 4 concurrent operations
coroutineScope {
    val files = (1..100).map { index ->
        async(limitedIo) {
            downloadFile("file_$index")
        }
    }
    files.awaitAll()
}

Coroutine'in bekleyerek zaman geçirdiği (G/Ç bağlamlı) tüm işlemler için IO dağıtıcısını kullanın. IO dağıtıcısındaki CPU yoğun görevler verimsizdir — G/Ç için ayrılmış iş parçacıklarını işgal ederek sistemin verimini düşürürler.

Dispatchers.Default: CPU Yoğun Görevler

Dispatchers.Default, işlemciyi yükleyen hesaplama işlemleri için dağıtıcıdır: sıralama, filtreleme, JSON ayrıştırma (Moshi, Kotlinx Serialization), görüntü işleme, hesaplamalar. Havuz boyutu, işlemci çekirdeği sayısına eşittir (ancak 2'den az değil). Bu, bağlam değiştirme olmadan maksimum CPU kullanımını sağlar.

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

G/Ç işlemleri için Dispatchers.Default kullanmayın — bu, hesaplama görevlerini işleyebilecek CPU havuzu iş parçacıklarını bloke eder. IO ve Default'u ayırmak, sistem kaynaklarının optimum kullanımını sağlar: IO iş parçacıkları G/Ç bekler, CPU iş parçacıkları sürekli hesaplamalarla meşgul olur.

Dispatchers.Unconfined: Geçerli İş Parçacığı

Dispatchers.Unconfined, bir coroutine'i herhangi bir havuza bağlamayan özel bir dağıtıcıdır. Coroutine, launch/async'in çağrıldığı iş parçacığında yürütmeye başlar ve askıya alındıktan sonra resume'u çağıran iş parçacığında devam eder. Bu davranış, sabit bir bağlam gerektirmeyen ara işlemler için uygundur.

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

Üretim kodunda Dispatchers.Unconfined nadiren kullanılır. Ana kullanım durumları: verileri başka bir dağıtıcıya aktarmadan önce hafif dönüşümler ve testler. Üretim iş yükleri için açık dağıtıcılar kullanın — Unconfined öngörülemezdir çünkü yürütme iş parçacığı resume uygulamasına bağlıdır.

Dağıtıcı Nasıl Seçilir

Dağıtıcı seçimi görev türüne bağlıdır: UI işlemleri → Main, G/Ç bağlamlı → IO, CPU bağlamlı → Default, ara → kapsamdan devralma. Android için, coroutine'in ana çalışmanın yapıldığı dağıtıcıda başlatılması ve UI'yi güncellemeden önce withContext aracılığıyla Main'e geçilmesi önerilir.

  • Main dağıtıcısında G/Ç işlemleri çalıştırmayın — bu UI'yi bloke eder
  • IO dağıtıcısında CPU yoğun görevler çalıştırmayın — bu IO havuzu iş parçacıklarını verimsiz tüketir
  • Toplu G/Ç işlemleri sırasında eşzamanlılığı kontrol etmek için limitedParallelism kullanın
  • Yeni kapsam oluşturmak yerine withContext kullanarak dağıtıcı değiştirin
  • Coroutine belirli bir havuz gerektirmiyorsa kapsamdan dağıtıcıyı devralın

Karmaşık senaryolar için, + operatörünü kullanarak dağıtıcıları birleştirin: Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler. Bu, belirtilen bir dağıtıcı, hata işleme ve izole bir Job hiyerarşisi ile bir CoroutineContext oluşturur.

Sıkça Sorulan Sorular

Dispatchers.IO ve Dispatchers.Default arasındaki fark nedir?

Dispatchers.IO, G/Ç bağlamlı işlemler (G/Ç bekleme) için 64 iş parçacığına kadar bir havuz kullanırken, Dispatchers.Default hesaplama görevleri için CPU çekirdeği sayısına göre bir havuz kullanır. İş parçacıkları kıt olduğunda, her iki havuz da birbiriyle iş parçacığı paylaşabilir.

Kotlin Coroutines'de kendi dağıtıcımı oluşturabilir miyim?

Evet, tek iş parçacıklı için newSingleThreadContext() veya sabit havuz için newFixedThreadPoolContext() kullanın. Üretim için, mevcut dağıtıcılara dayalı limitedParallelism() kullanın — bu, yeni havuzlar oluşturmaktan daha verimlidir.

Arka plan iş parçacığından Dispatchers.Main çağrıldığında ne olur?

Dispatchers.Main kullanılamıyorsa (örneğin, bir JUnit testinde veya arka plan hizmetinde), bir IllegalStateException fırlatılır. Testler için TestCoroutineDispatcher ve arka plan hizmetleri için Dispatchers.IO veya Default kullanın.

Paralel G/Ç işlemlerinin sayısı nasıl sınırlanır?

Dispatchers.IO.limitedParallelism(N) kullanın, burada N maksimum paralel iş parçacığı sayısıdır. Bu, toplu istekler sırasında havuzun tükenmesini önler ve kontrollü paralellik sağlar.

Dispatchers.Unconfined ne zaman kullanılır?

Dispatchers.Unconfined ara işlemler için uygundur: başka bir dağıtıcıya aktarmadan önce hafif veri dönüşümleri, test senaryoları. Üretim Android kodunda, askıya alındıktan sonra tanımsız yürütme iş parçacığı nedeniyle önerilmez.

Özet

  • Dispatchers — coroutine yürütme iş parçacıklarını belirleyen CoroutineContext bileşenleri
  • Dispatchers.Main — Android UI işlemleri için, bir ana iş parçacığı
  • Dispatchers.IO — ağ ve disk işlemleri için, 64 iş parçacığına kadar havuz
  • Dispatchers.Default — CPU yoğun hesaplamalar için, çekirdek sayısına göre havuz
  • Dispatchers.Unconfined — iş parçacığı bağlaması olmadan, ara işlemler için
  • withContext — bir coroutine içinde dağıtıcılar arasında geçiş yapmanın ana mekanizması
  • Yanlış dağıtıcı seçimi UI gecikmelerine veya verimsiz kaynak kullanımına yol açar

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun