Middle+
Kuidas saab Kotlinis korutinatega sünkroniseerimist rakendada?
sobes.tech AI
Vastus AI-lt
Kotlin korutinatesünteesi saavutatakse spetsiaalsete primitiivide ja andmestruktuuride abil kotlinx.coroutines teegist.
Peamised lähenemised:
-
Mutex
- Tagab vastastikuse välistuse kriitilistes sektsioonide kaitsmiseks.
- Korutin, mis üritab Mutex-i saada, blokeerub kuni see vabastatakse.
- Omab
lock()jaunlock()funktsioone ning ka rohkem idiomaatilistwithLock.
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) // Ootame 10000 } -
Semaphore
- Piirab samaaegselt töötavate korutinote arvu, mis saavad samaaegselt ressursile ligi või täita teatud koodi.
- Halda loa pulti.
- Omab
acquire()jarelease()funktsioone ningwithPermit.
import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.* val semaphore = Semaphore(2) // Võib töötada korraga 2 korutinat suspend fun doLimitedWork(id: Int) { semaphore.withPermit { println("Korutina $id omandas loa. Töö käib...") delay(100) // Töö imitatsioon println("Korutina $id vabastas loa.") } } suspend fun main() = coroutineScope { repeat(5) { i -> launch { doLimitedWork(i) } } } -
Atomaarsed operatsioonid (
kotlinx.coroutines.atomic-ist)- Tagab voogudele ohutud operatsioonid primitiivide ja viidete üle.
- Kasutab madala taseme CPU juhiseid (CAS - Compare-and-Swap).
- Sobib lihtsateks operatsioonideks ilma ilmsete lukudeta.
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) // Ootame 10000 } -
Jagatud andmestruktuurid ühe-joonelise saatjaga
- Kõige lihtsam lähenemine.
Dispatchers.Default.limitedParallelism(1)võinewSingleThreadContextvõimaldab käivitada korutinaid ühe joone kontekstis, tagades järjekindla täitmise ja vältides andmerünnakuid. See ei ole otsene sünkroniseerimise primitiiv, kuid tagab sünkroniseerimise serialiseerimise kaudu.
import kotlinx.coroutines.* val mySingleThreadContext = newSingleThreadContext("SingleThread") var sharedData = mutableListOf<Int>() suspend fun addToSharedData(value: Int) { sharedData.add(value) // Ohutu, kuna toimub ühes joones } suspend fun main() = withContext(mySingleThreadContext) { repeat(10_000) { launch { addToSharedData(it) } } println(sharedData.size) // Ootame 10000 } - Kõige lihtsam lähenemine.
-
** Kanalid**
- Ei ole primitiivsed sünkroniseerimiseks, kuid võivad olla kasutatavad turvaliseks andmeedastuseks korutinide vahel, mis kaudselt lahendab juurdepääsu probleemid edastatavate andmete osas.
- Pakuvad võimalust andmevoo edastamiseks ühest korutinas teise.
Valik sõltub kasutusstsenaariumist. Mutex ja Semaphore pakuvad klassikalisi lukustusmehhanisme, Atomaarsete operatsioonide tõhusus on lihtsate atomaarsete uuenduste jaoks, ning ühe-joonelise saatja kasutamine on mugav, kui juurdepääs ühistele andmetele peab olema rangelt järjestikune. Kanalid kasutatakse kommunikatsiooniks ja koordineerimiseks, mitte otse ühiste ressursside kaitseks.