Sobes.tech
Middle

Kotlin, asenkron işlemlerle çalışmak için hangi imkanları sağlar?

sobes.tech yapay zeka

AI'dan gelen yanıt

Kotlin, asenkron işlemleri basitleştirmek için hafif iş parçacıkları sağlayan koroutine'ler (coroutines) sunar ve böylece ana iş parçacığını engellemez.

Ana özellikler:

  • Askıya Alma Fonksiyonları: suspend anahtar kelimesiyle tanımlanan ve askıya alınıp devam ettirilebilen fonksiyonlar. Bu fonksiyonlar çalıştıkları iş parçacığını engellemez.
    suspend fun fetchData(): String {
        delay(1000) // Uzun süren bir işlemi taklit eder
        return "Veri alındı"
    }
    
  • Koroutine Yapıcıları: Koroutine başlatmak için kullanılan fonksiyonlar:
    • launch: Yeni bir koroutine başlatır ve Job döner (engellemez).
      GlobalScope.launch {
          println("Koroutine başlatıldı")
      }
      
    • async: Yeni bir koroutine başlatır ve Deferred<T> döner (.await() çağrısında bloklanır).
      val deferred = GlobalScope.async {
          fetchData()
      }
      // ...
      val result = deferred.await() // Sonucu bekler
      
    • runBlocking: Koroutine tamamlanana kadar mevcut iş parçacığını bloklar (testlerde ve bloklayıcı kodlar arasında köprü kurmak için kullanılır).
      runBlocking {
          val data = fetchData()
          println(data)
      }
      
  • Koroutine Bağlamı: Koroutine'nin davranışını belirleyen öğelerin kümesi, Dispatcher ve Job dahil.
    • Dispatcher: Koroutine'nin çalıştığı iş parçacığını veya iş parçacığı havuzunu belirler.
  • Dispatchers: İş parçacıklarını yönetmek için yerleşik nesneler:
    • Dispatchers.Default: Paylaşılan arka plan iş parçacığı havuzu.
    • Dispatchers.IO: Giriş/Çıkış işlemleri için optimize edilmiştir (disk, ağ işlemleri).
    • Dispatchers.Main: Ana UI iş parçacığı (Android, JavaFX vb. için).
    • Dispatchers.Unconfined: Koroutine'yi mevcut iş parçacığında başlatır, ancak askıya alındıktan sonra herhangi bir iş parçacığında devam edebilir.
    GlobalScope.launch(Dispatchers.IO) {
        // Giriş/Çıkış iş parçacığında çalışır
    }
    
  • Yapısal Eşzamanlılık: Koroutine'lerin ebeveyni (CoroutineScope) vardır ve ebeveyn iptal edildiğinde otomatik olarak iptal edilirler. Kaynak sızıntılarını önler ve yaşam döngüsü yönetimini kolaylaştırır.
    // CoroutineScope otomatik olarak çocuk koroutine'leri yönetir
    val scope = CoroutineScope(Dispatchers.Default)
    val job = scope.launch {
        // ...
    }
    // scope iptal edilirse, tüm çocuk koroutine'ler iptal edilir
    scope.cancel()
    
  • Kanallar: Koroutine'ler arasında güvenli veri iletimi için kullanılır. Şunlar olabilir:
    • Unbuffered: Alım, yalnızca gönderimden sonra gerçekleşir.
    • Buffered: Birkaç öğe gönderilene kadar bloklamadan gönderim yapabilir.
    • Conflated: Sadece en son gönderilen öğeyi tutar.
    val channel = Channel<Int>()
    
    scope.launch {
        for (x in 1..5) channel.send(x)
        channel.close()
    }
    
    scope.launch {
        for (y in channel) println(y)
    }
    
  • Akış (Flow): Birden fazla değeri asenkron olarak yayabilen veri akışıdır. RxJava Observable'a benzer, ancak daha hafif ve koroutine'lerle entegre edilmiştir.
    fun simpleFlow(): Flow<Int> = flow {
        for (i in 1..3) {
            delay(100)
            emit(i) // Değeri gönder
        }
    }
    
    runBlocking {
        simpleFlow().collect { value -> println(value) } // Değerleri tüket
    }
    

Bu özellikler, çağrı geri aramaları veya Future kullanımı yerine, daha okunabilir ve sürdürülebilir bir şekilde asenkron kod yazmayı sağlar.