Sobes.tech
Middle+

Kotlin-də koroutinlər istifadə edərək sinxronizasiyanı necə həyata keçirmək olar?

sobes.tech Süni İntellekt

AI-dan cavab

Kotlin korutinlərində sinxronizasiya kotlinx.coroutines kitabxanasından xüsusi primitive və məlumat strukturları vasitəsilə həyata keçirilir.

Əsas yanaşmalar:

  1. Mutex

    • Kritik kod bölmələrini qorumaq üçün qarşılıqlı istisna təmin edir.
    • Mutex əldə etməyə çalışan korutin, sərbəst buraxılana qədər bloklanır.
    • lock()unlock() funksiyalarına əlavə olaraq, daha çox idiomatiki withLock funksiyası var.
    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    import kotlinx.coroutines.*
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun increment() {
        mutex.withLock {
            counter++
        }
    }
    
    suspend fun main() = coroutineScope {
        repeat(10_000) {
            launch {
                increment()
            }
        }
        println(counter) // Gözlənilir 10000
    }
    
  2. Semaphore

    • Eyni anda resursa giriş edə biləcək korutinlərin sayını məhdudlaşdırır.
    • İcazə hovuzunu idarə edir.
    • acquire()release() funksiyalarına əlavə olaraq, withPermit var.
    import kotlinx.coroutines.sync.Semaphore
    import kotlinx.coroutines.sync.withPermit
    import kotlinx.coroutines.*
    
    val semaphore = Semaphore(2) // Eyni zamanda 2 korutin işləyə bilər
    
    suspend fun doLimitedWork(id: Int) {
        semaphore.withPermit {
            println("Korutin $id icazə aldı. İşləyir...")
            delay(100) // İşin təqlidi
            println("Korutin $id icazəni sərbəst buraxdı.")
        }
    }
    
    suspend fun main() = coroutineScope {
        repeat(5) { i ->
            launch {
                doLimitedWork(i)
            }
        }
    }
    
  3. Atomik əməliyyatlar (kotlinx.coroutines.atomic-dən)

    • İplik təhlükəsiz əməliyyatlar təmin edir, primitive tiplər və referanslar üzərində.
    • Aşağı səviyyəli CPU əmrlərindən (CAS - Compare-and-Swap) istifadə edir.
    • Sadə əməliyyatlar üçün uyğundur, açıq bloklamalar olmadan.
    import kotlinx.coroutines.atomic.AtomicInt
    import kotlinx.coroutines.*
    
    val atomicCounter = AtomicInt(0)
    
    suspend fun atomicIncrement() {
        atomicCounter.incrementAndGet()
    }
    
    suspend fun main() = coroutineScope {
        repeat(10_000) {
            launch {
                atomicIncrement()
            }
        }
        println(atomicCounter.value) // Gözlənilir 10000
    }
    
  4. Tək iplikli dispatcher-də paylaşılan məlumat strukturları

    • Ən sadə yanaşma. Korutinləri tək iplikli kontekstdə işlətmək (Dispatchers.Default.limitedParallelism(1) və ya newSingleThreadContext) kodun ardıcıl icrasını təmin edir, məlumatların yarışmasını istisna edir. Bu, açıq sinxronizasiya primitive deyil, lakin girişin seriyalaşdırılması ilə sinxronizasiya təmin edir.
    import kotlinx.coroutines.*
    
    val mySingleThreadContext = newSingleThreadContext("SingleThread")
    var sharedData = mutableListOf<Int>()
    
    suspend fun addToSharedData(value: Int) {
        sharedData.add(value) // Eyni iplikdə icra olunduğu üçün təhlükəsiz
    }
    
    suspend fun main() = withContext(mySingleThreadContext) {
        repeat(10_000) {
            launch {
                 addToSharedData(it)
            }
        }
        println(sharedData.size) // Gözlənilir 10000
    }
    
  5. Kanalardan istifadə

    • Əsasən sinxronizasiya primitive deyil, lakin məlumatların təhlükəsiz ötürülməsi üçün istifadə oluna bilər, bu da məlumatların girişinə nəzarəti dolayı yolla həll edir.
    • Bir korutindən digərinə məlumat axını ötürmək üçün vasitədir.

İstifadə ssenarisinə görə yanaşma seçimi dəyişir. Mutex və Semaphore klassik kilidləmə mexanizmləri təqdim edir, Atomik əməliyyatlar sadə atomik yeniləmələr üçün effektivdir, tək iplikli dispatcher isə məlumatlara girişin ardıcıl olmasını tələb etdiyində əlverişlidir. Kanallar isə kommunikasiya və koordinasiya üçün istifadə olunur, birbaşa ümumi resursların qorunması üçün deyil.