Sobes.tech
Middle+

Kaip sinchronizuoti korutinas Android?

sobes.tech AI

Atsakymas iš AI

„Android“ korutinų sinchronizavimui galima naudoti keletą būdų, priklausomai nuo konkretaus užduoties:

  • Join: laukti kitos korutinės užbaigimo:

    // paleidžiame pirmąją korutiną
    val job1 = CoroutineScope(Dispatchers.Default).launch {
        delay(1000)
        println("Darbas 1 baigtas")
    }
    
    // paleidžiame antrąją korutiną
    val job2 = CoroutineScope(Dispatchers.Default).launch {
        delay(500)
        println("Darbas 2 baigtas")
    }
    
    // laukiame abiejų korutinų pabaigos
    job1.join()
    job2.join()
    
    println("Visi darbai baigti")
    
  • Await: laukti asinchroninės operacijos rezultato, kuris yra Deferred:

    // asinchroninė operacija, grąžinanti rezultatą
    val deferredResult = CoroutineScope(Dispatchers.Default).async {
        delay(1000)
        "Rezultatas iš async"
    }
    
    // laukiame rezultato
    val result = deferredResult.await()
    println(result)
    
  • CoroutineScope.coroutineScope: sukurti naują matomumo sritį, kuri baigsis tik po visų vaikų korutinų pabaigos. Naudinga struktūrizuotai konkurencijai:

    suspend fun doParallelWork() {
        coroutineScope { // sukurti naują struktūrizuotą konkurencijos sritį
            launch { delay(1000); println("Užduotis 1 baigta") }
            launch { delay(500); println("Užduotis 2 baigta") }
        } // ši vieta bus pasiekta tik po užduočių 1 ir 2 pabaigos
        println("Visi paraleliniai darbai baigti")
    }
    
  • Aktorų semantika (Channel): žinučių mainams ir prieigos sinchronizacijai keičiamų duomenų tarp korutinų:

    // sukurti kanalą Int keitimui
    val channel = Channel<Int>()
    
    CoroutineScope(Dispatchers.Default).launch {
        // siųsti duomenis į kanalą
        for (i in 1..5) {
            channel.send(i)
        }
        channel.close() // uždaryti kanalą po siuntimo
    }
    
    CoroutineScope(Dispatchers.Default).launch {
        // gauti duomenis iš kanalo
        for (value in channel) {
            println("Gauta $value")
        }
    }
    
  • Mutex: užtikrinti išskirtinį prieigą prie bendro ištekliaus:

    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun incrementCounter() {
        mutex.withLock { // įgyti mutex
            counter++
        }
    }
    

Pasirinkimas priklauso nuo to, ką tiksliai reikia sinchronizuoti: laukti užbaigimo, gauti rezultatą, valdyti paralelines užduotis, keistis duomenimis ar turėti išskirtinę prieigą. coroutineScope yra rekomenduojamas būdas kaip numatytasis struktūrizuotos konkurencijos sprendimas.