Sobes.tech
Middle+

Kotlin'de çok iş parçacıklı programlama ile nasıl çalışıyorsunuz?

sobes.tech yapay zeka

AI'dan gelen yanıt

Kotlin'de çoklu iş parçacığıyla çalışmak için genellikle korutinler kullanıyorum. Bunlar, geleneksel iş parçacıklarına kıyasla daha hafif ve esnek bir yaklaşım sağlar, yükü azaltır ve paralel işlemlerin yönetimini basitleştirir.

Korutinlerle çalışırken temel kavramlar:

  • Suspend fonksiyonlar: Duraklatılabilir ve yeniden başlatılabilir fonksiyonlar. Bunlar, korutinlerde asenkron işlemler için temel oluşturur.
    suspend fun fetchData(): String {
        delay(1000) // Örnek duraklatma
        return "Veri alındı"
    }
    
  • CoroutineScope: Korutinlerin yaşam döngüsünü belirler ve iptal etmeyi sağlar.
    import kotlinx.coroutines.*
    
    fun main() = runBlocking { // Bloklayıcı yürütme için CoroutineScope
        launch { // Bu Scope içinde yeni bir korutin oluşturma
            // Korutin kodu
        }
    }
    
  • Dispatchers (İş Dağıtıcılar): Korutinin çalışacağı işçi havuzunu belirler.
    • Dispatchers.Default: CPU yoğun hesaplamalar için.
    • Dispatchers.IO: Bloklayıcı I/O işlemleri için (örneğin, ağ veya dosya işlemleri).
    • Dispatchers.Main: UI ile çalışma (uygulama platformlarına uygun olarak erişilebilir, örneğin Android).
    • Dispatchers.Unconfined: Belirli bir işçi havuzuna bağlı değildir.
    import kotlinx.coroutines.*
    
    suspend fun doSomethingAsync() {
        withContext(Dispatchers.IO) { // I/O dağıtıcıya geçiş
            // Bloklayıcı işlemi gerçekleştir
        }
    }
    
  • Korutin Yapıcıları: Korutinleri başlatmak için fonksiyonlar.
    • launch: Bir korutini başlatır ve Job döner, bu da iptal etmek için kullanılabilir.
    • async: Bir korutini başlatır ve Deferred döner, bu da sonucu await() ile almayı sağlar.
    import kotlinx.coroutines.*
    
    suspend fun example() {
        val job = launch {
            // Paralel görev
        }
    
        val deferredResult = async {
            // Sonuç döndüren görev
            "Sonuç"
        }
    
        job.cancel() // Görevi iptal et
        val result = deferredResult.await() // Sonucu al
    }
    

Ortak kaynaklara erişimi senkronize etmek için kotlinx.coroutines.sync paketinden araçlar kullanıyorum, örneğin Mutex veya Semaphore.

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.*

val mutex = Mutex()
var counter = 0

suspend fun incrementCounter() {
    mutex.withLock { // Ortak kaynağa erişim öncesi Mutex kilidi
        counter++
    }
}

Bazı özel durumlarda, düşük seviyede doğrudan iş parçacıklarını yönetmek gerekirse, java.util.concurrent paketinden sınıflar veya doğrudan Thread ve Runnable sınıflarını kullanabilirim, ancak bu korutinlere göre çok daha nadiren kullanılır.

Korutinlerin geleneksel iş parçacıklarına göre avantajları:

Özellik Korutinler Geleneksel iş parçacıkları
Ağırlık Hafif, tek bir iş parçacığında çok sayıda Ağır, her iş parçacığı kaynak kullanır
Geçiş İşbirlikçi (suspend/resume) Zorunlu (İşletim sistemi zamanlayıcısı)
İptal Kolay ve yapılandırılmış Karmaşık, kesintilerin yönetilmesi gerekir
Hata ayıklama Kullanışlı, yığın izi korunur Zor olabilir
Yapı Yapılandırılmış eşzamanlılığı destekler Daha az yapılandırılmış

Korutinleri, verimlilikleri, asenkron kod yazımındaki sadelikleri ve özellikle karmaşık asenkron işlemler dizisiyle çalışırken daha iyi okunabilirlikleri nedeniyle tercih ediyorum.