Sobes.tech
Middle+

Kotlinде корутиндерди колдонуп синхрондоштурууну кантип ишке ашырууга болот?

sobes.tech AI

AIден жооп

Котлин корутиндеринде синхрондаштыруу kotlinx.coroutines китепканасынан алынган атайын примитивдер жана маалымат структуралары аркылуу жетишилет.

Негизги ыкмалар:

  1. Mutex

    • Критикалык бөлүктөрдү коргоо үчүн өз ара исключениени камсыздайт.
    • Mutexти алуу аракетиндеги корутина токтоп калат, ал аны бошотконго чейин.
    • lock() жана unlock() функциялары бар, ошондой эле көбүрөөк идиоматикалык withLock бар.
    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) // 10000 күтүлүүдө
    }
    
  2. Semaphore

    • Бир убакта иштей турган корутиндердин санын чектейт, ресурска же белгилүү бир код бөлүгүнө бир мезгилде жетүүгө мүмкүндүк берет.
    • уруксаттар пулун башкаруу.
    • acquire() жана release() функциялары бар, ошондой эле withPermit бар.
    import kotlinx.coroutines.sync.Semaphore
    import kotlinx.coroutines.sync.withPermit
    import kotlinx.coroutines.*
    
    val semaphore = Semaphore(2) // Бир убакта 2 корутина иштей алат
    
    suspend fun doLimitedWork(id: Int) {
        semaphore.withPermit {
            println("Корутина $id уруксат алды. Ишке кирүү...")
            delay(100) // Ишти имитациялоо
            println("Корутина $id уруксатты бошотту.")
        }
    }
    
    suspend fun main() = coroutineScope {
        repeat(5) { i ->
            launch {
                doLimitedWork(i)
            }
        }
    }
    
  3. Атомардык операциялар (kotlinx.coroutines.atomicтен)

    • Туура иштөө үчүн потокко коопсуз операцияларды primitives жана шилтемелер үстүндө камсыздайт.
    • төмөн деңгээлдеги CPU көрсөтмөлөрүн (CAS - Compare-and-Swap) колдонуу.
    • жөнөкөй операциялар үчүн ылайыктуу, ачык блокторсуз.
    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) // 10000 күтүлүүдө
    }
    
  4. Бир-тайптуу диспетчер менен бөлүштүрүлгөн маалымат структуралары

    • эң жөнөкөй ыкма. Dispatchers.Default.limitedParallelism(1) же newSingleThreadContext колдонуу бир тармактуу контекстте корутиндерди иштетүү, маалыматтардын катарлаш иштешин камсыз кылат, бул гонкалардын алдын алат. Бул ачык синхрондаштыруу primitive эмес, бирок сериализация аркылуу синхрондуулук камсыз кылат.
    import kotlinx.coroutines.*
    
    val mySingleThreadContext = newSingleThreadContext("SingleThread")
    var sharedData = mutableListOf<Int>()
    
    suspend fun addToSharedData(value: Int) {
        sharedData.add(value) // Коопсуз, анткени бир тармакта иштейт
    }
    
    suspend fun main() = withContext(mySingleThreadContext) {
        repeat(10_000) {
            launch {
                 addToSharedData(it)
            }
        }
        println(sharedData.size) // 10000 күтүлүүдө
    }
    
  5. Channels

    • Ачуу синхрондаштыруу primitive эмес, бирок корутиндер арасында маалыматтарды коопсуз өткөрүү үчүн колдонулушу мүмкүн, бул косвенно жеткиликтүү маалыматтарга жетүүнүн проблемаларын чечет.
    • Бир корутинадан экинчи корунага маалымат агымын өткөрүүчү ыкма.

Тандоо колдонуу сценарийине жараша болот. Mutex жана Semaphore классикалык блоктоо механизмдерин камсыздайт, Atomic операциялар жөнөкөй атомардык жаңыртуулар үчүн эффективдүү, ал эми бир-тайптуу диспетчер катуу тартипте жалпы маалыматка жетүүнү талап кылганда ыңгайлуу. Channels коммуникация жана координация үчүн колдонулат, түз эле жалпы ресурстарды коргоо үчүн эмес.