Sobes.tech
Middle+

Wie synchronisiert man Koroutinen in Android?

sobes.tech KI

Antwort von AI

Um Coroutinen in Android zu synchronisieren, können je nach Aufgabe verschiedene Ansätze verwendet werden:

  • Join: Warten auf das Ende einer anderen Coroutine.

    // Erste Coroutine starten
    val job1 = CoroutineScope(Dispatchers.Default).launch {
        delay(1000)
        println("Job 1 beendet")
    }
    
    // Zweite Coroutine starten
    val job2 = CoroutineScope(Dispatchers.Default).launch {
        delay(500)
        println("Job 2 beendet")
    }
    
    // Warten auf beide Coroutinen
    job1.join()
    job2.join()
    
    println("Alle Jobs beendet")
    
  • Await: Warten auf das Ergebnis einer asynchronen Operation, dargestellt durch Deferred.

    // Asynchrone Operation, die ein Ergebnis zurückgibt
    val deferredResult = CoroutineScope(Dispatchers.Default).async {
        delay(1000)
        "Ergebnis von async"
    }
    
    // Ergebnis abwarten
    val result = deferredResult.await()
    println(result)
    
  • CoroutineScope.coroutineScope: Erstellen eines neuen Geltungsbereichs, der nur nach Abschluss aller Kind-Coroutinen endet. Nützlich für strukturierte Konkurrenz.

    suspend fun doParallelWork() {
        coroutineScope { // Erstellen eines neuen strukturierten Concurrency-Scopes
            launch { delay(1000); println("Aufgabe 1 beendet") }
            launch { delay(500); println("Aufgabe 2 beendet") }
        } // Dieser Punkt wird nur erreicht, nachdem Aufgabe 1 und 2 beendet sind
        println("Alle parallelen Aufgaben beendet")
    }
    
  • Semantik der Akteure (Channel): Für den Nachrichtenaustausch und die Synchronisation des Zugriffs auf änderbare Daten zwischen Coroutinen.

    // Erstellen eines Kanals für den Austausch von Int
    val channel = Channel<Int>()
    
    CoroutineScope(Dispatchers.Default).launch {
        // Daten in den Kanal senden
        for (i in 1..5) {
            channel.send(i)
        }
        channel.close() // Kanal nach dem Senden schließen
    }
    
    CoroutineScope(Dispatchers.Default).launch {
        // Daten aus dem Kanal empfangen
        for (value in channel) {
            println("Empfangen $value")
        }
    }
    
  • Mutex: Für die Gewährleistung eines exklusiven Zugriffs auf eine gemeinsame Ressource.

    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun incrementCounter() {
        mutex.withLock { // Mutex sperren
            counter++
            // Mutex wird automatisch beim Verlassen des Blocks freigegeben
        }
    }
    

Die Wahl der Methode hängt davon ab, was genau synchronisiert werden muss: Abschluss abwarten, Ergebnis erhalten, parallele Aufgaben verwalten, Daten austauschen oder exklusiven Zugriff. coroutineScope ist der empfohlene Ansatz für strukturierte Konkurrenz.