Coroutines (korutinler), kotlinx.coroutines kütüphanesi aracılığıyla kullanılabilen, Kotlin'de asenkron programlama için hafif thread'lerdir. JetBrains Kotlin Documentation, 2026'ya göre, Coroutines, geleneksel Thread'lerin aksine, bir thread'i bloke etmeden fonksiyon yürütmeyi askıya alabilir. Korutinler sınırlı bir thread havuzunda çalışır ve bu da onları yerel thread'lerden bin kat daha hafif yapar. Kotlin Coroutines, Android Jetpack, Retrofit, Room ve Android ekosisteminin diğer popüler kütüphaneleriyle tamamen entegredir.
Önemli Noktalar
Coroutines, kotlinx.coroutines kütüphanesinde uygulanan Kotlin'de bir asenkron programlama mekanizmasıdır. İşletim sistemi thread'lerinin aksine, korutinler belirli bir thread'e bağlı değildir: bir thread'de askıya alınabilir ve başka bir thread'de devam edebilir. Tek bir thread, minimum ek yük ile aralarında geçiş yaparak binlerce korutini yürütebilir.
Korutinler, Kotlin 1.3'te (2018) deneysel bir özellik olarak ortaya çıktı ve Kotlin 1.5'te (2021) kararlı hale geldi. Coroutines, callback hell sorununu async/await benzeri şekilde çözer, ancak daha zengin bir API sağlar: kanallar (Channel), Flow, Job hiyerarşisinde istisna yönetimi ve Android Lifecycle ile doğrudan entegrasyon.
JetBrains'e (2025) göre, her korutin yaklaşık 100 bayt bellek tüketirken, yerel bir thread 1+ MB tüketir. Bu, OutOfMemoryError riski olmadan tek bir uygulamada milyonlarca korutin çalıştırmaya olanak tanır. Korutinlerin hafifliği, onları Android'de asenkronluk için tercih edilen araç haline getirir.
Her Kotlin korutini, Continuation Passing Style (CPS) kullanılarak bir durum makinesine derlenir. Derleyici, her suspend fonksiyonuna gizli bir Continuation parametresi ekler. Continuation, devam noktasını ve tüm yerel değişkenleri içerir. Bir korutin askıya alındığında, çalışma zamanı Continuation'ı kaydeder ve devam ettiğinde, Dispatcher havuzundaki herhangi bir uygun thread'de geri yükler.
suspend, bir fonksiyonu askıya alınabilir olarak işaretleyen bir Kotlin anahtar kelimesidir. Böyle bir fonksiyon yalnızca başka bir suspend fonksiyonundan veya bir korutinden çağrılabilir. Bir suspend fonksiyonunun içinde, diğer suspend fonksiyonlarını herhangi bir sırayla çağırabilirsiniz ve her çağrı noktası potansiyel bir askıya alma noktasıdır.
Mekanik basittir: bir suspend fonksiyonu başka bir suspend fonksiyonunu çağırdığında, o noktada askıya alınır ve thread'i serbest bırakır. Çağrılan fonksiyon tamamlandıktan sonra, çalışma zamanı kaydedilen konumdan yürütmeye devam eder. Buna işbirlikçi iptal (cooperative cancellation) denir — hiçbir thread bloke edilmez.
Önemli: bir suspend fonksiyonu varsayılan olarak asenkron değildir. launch veya async kullanılmazsa yürütme sırası sıralı kalır. suspend yalnızca fonksiyonun thread'i bloke etmeden duraklamasına ve korutin bağlamının bir parçası olmasına izin verir. Continuation Passing Style, her suspend fonksiyonunun gizli bir Continuation geri çağrısı aldığı ve derleyicinin askıya almaları ve devam ettirmeleri yönetmek için bir durum makinesi oluşturduğu bir derleme modelidir.
CoroutineScope, korutinlerin yaşam döngüsünü tanımlayan bir bağlamdır. Tüm korutinler bir kapsam içinde başlatılmalıdır. Bir kapsam iptal edildiğinde (örneğin, bir Activity sona erdiğinde), tüm alt korutinleri otomatik olarak iptal edilir. Bu, arka plan görev sızıntılarını önler. Android Jetpack, her bileşen için hazır kapsamlar sağlar: ViewModel için viewModelScope ve Activity/Fragment için lifecycleScope, ilgili bileşen yok edildiğinde otomatik olarak iptal edilir.
Yapılandırılmış Eşzamanlılık (Structured Concurrency), tüm alt korutinler tamamlanana kadar bir korutinin tamamlanmayacağını garanti eden bir ilkedir. Job hiyerarşisi bir ağaç oluşturur: bir kök korutin bir üst job oluşturur, alt job'lar oluşturur. Bir üst job'ın iptali tüm alt job'lara yayılır. Structured Concurrency, korutinler ve thread'ler arasındaki temel bir farktır.
| Scope | Nerede Kullanılır | İptal |
|---|---|---|
| GlobalScope | Yalnızca daemon görevleri için | Otomatik iptal edilmez |
| viewModelScope | Android ViewModel | ViewModel temizlendiğinde |
| lifecycleScope | Android Activity/Fragment | lifecycle yok edildiğinde |
| coroutineScope | suspend fonksiyonu içinde | Üst job iptal edildiğinde |
Normal bir Job, bir alt korutin başarısız olduğunda tüm kardeşleri iptal eder. SupervisorJob bir istisnadır: bir alt korutindeki başarısızlık diğerlerini etkilemez. Bu, birden fazla bağımsız görevin paralel olarak yürütüldüğü ve bunlardan birinin diğerlerini iptal etmeye gerek kalmadan çökebileceği durumlarda önemlidir.
Dispatchers, korutinlerin hangi thread'lerde yürütüleceğini belirler. Dispatchers.Main — ana Android UI thread'i. Dispatchers.IO — bloke edici işlemler (ağ, disk) için bir havuz. Dispatchers.Default — CPU yoğun görevler için. Dispatchers.Unconfined — geçerli thread'de başlar ancak orada kalacağını garanti etmez. Doğru Dispatcher'ı seçmek performans için kritiktir: Default'ta bir IO görevi hesaplama havuzunu bloke ederken, IO'da bir CPU görevi gereksiz thread'ler oluşturur.
withContext — bir korutin içinde Dispatcher'ı değiştirmek için bir fonksiyondur. Örneğin, JSON ayrıştıran bir suspend fonksiyonu, hesaplama için Dispatchers.Default'a geçebilir ve UI güncellemesi için Dispatchers.Main'e dönebilir. withContext, Android geliştirmede en çok kullanılan oluşturucudur.
launch — bir korutin başlatır, Job döndürür, sonuç döndürmez (fire-and-forget). async — bir korutin başlatır, await ile sonucu alınabilecek bir Deferred döndürür. runBlocking — bir korutini yürütmek için geçerli thread'i bloke eder (yalnızca testler ve main fonksiyonları için). Oluşturucu seçimi senaryoya bağlıdır: launch olaylar ve güncellemeler için uygundur, async sonuç gerektiren görevler için, runBlocking yalnızca testler veya giriş noktaları için.
Üç pratik senaryoyu inceleyelim: launch ile temel bir korutin, async ile paralel çağrı ve SupervisorJob ile hata yönetimi.
viewModelScope.launch, ViewModel bağlamında bir korutin başlatır. ViewModel temizlendiğinde korutin otomatik olarak iptal edilir.
class ProfileViewModel : ViewModel() {
fun loadUser() {
viewModelScope.launch(Dispatchers.IO) {
val user = api.fetchUser()
withContext(Dispatchers.Main) {
showUser(user)
}
}
}
}
coroutineScope ile async, üç isteği paralel olarak başlatır. Sonuçlar .await() ile toplanır. Herhangi bir istek başarısız olursa tümü iptal edilir.
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, her korutinin bağımsız olarak tamamlanmasını sağlar. Bir istekteki hata diğerlerini iptal etmez.
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) }
}
Thread'ler bir işletim sistemi ilkelidir. Her thread'in kendi yığını (~1 MB) vardır ve oluşturma ve değiştirme için sistem çağrısı gerektirir. Korutinler bir dil ilkelidir, işletim sistemine bağlı değildir. Durumu kaydetmek için Continuation kullanır ve sistem çağrısı olmadan çalışma zamanı seviyesinde geçiş yapar.
Google'a (2025) göre, thread'ler yerine korutin kullanmak, Android uygulamalarındaki arka plan görevleri için bellek tüketimini %90-95 oranında azaltır. Tüm modern Android kütüphaneleri (Retrofit, Room, WorkManager), suspend fonksiyonları aracılığıyla yerleşik korutin desteğine sahiptir. Ktor (JetBrains HTTP istemci çerçevesi) da tamamen korutinler üzerine inşa edilmiştir ve geri çağrı API'si olmadan her istek için suspend fonksiyonları sağlar. Room, DAO'daki suspend fonksiyonları aracılığıyla korutinleri destekleyerek ana thread'i bloke etmeden veritabanı sorguları yürütülmesine olanak tanır.
Thread'ler, JNI aracılığıyla yerel kod, uzun süreli CPU yoğun bloke edici çağrılar (video işleme, simülasyonlar) ve C kütüphaneleriyle entegrasyon için gereklidir. Diğer her şey için — korutinler.
Sıkça Sorulan Sorular
Korutin, mevcut bir thread'de yürütülen askıya alınabilir bir iş birimdir. Thread, kendi yığınına sahip bir sistem kaynağıdır. Korutinler thread'lerden binlerce kat daha hafiftir ve askıya alındığında kaynakları bloke etmez.
Dispatchers.IO, bloke edici G/Ç işlemleri (ağ, dosyalar) için tasarlanmıştır ve gerektiğinde yeni thread'ler oluşturabilir. Dispatchers.Default, CPU yoğun hesaplamalar için sabit boyutlu bir havuza (CPU çekirdeği sayısı) sahiptir.
Job.cancel() korutini ve tüm alt korutinlerini iptal eder. Bir korutin içinde iptali kontrol etmek için ensureActive() kullanın — korutin iptal edilmişse CancellationException fırlatır.
Evet — kotlinx-coroutines-rx3 kütüphanesi aracılığıyla. Observable/Single'ı suspend fonksiyonlarına dönüştürmek ve flowable aracılığıyla geri döndürmek için awaitSingle, awaitFirst ve diğer fonksiyonları sağlar.
Flow, soğuk asenkron veri akışıdır ve korutinlerde RxJava Observable'ın eşdeğeridir. Flow değerleri sırayla yayar ve bir istisna veya başarı ile tamamlanır. map, filter, catch ve diğer operatörleri destekler.
Özet
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.
Ayrıca okuyun