Sobes.tech
Middle+

Comment synchroniser les coroutines sur Android?

sobes.tech IA

Réponse de l'IA

Pour synchroniser les coroutines en Android, plusieurs approches peuvent être utilisées, en fonction de la tâche spécifique :

  • Join : Attendre la fin d'une autre coroutine.

    // Démarrer la première coroutine
    val job1 = CoroutineScope(Dispatchers.Default).launch {
        delay(1000)
        println("Job 1 terminé")
    }
    
    // Démarrer la deuxième coroutine
    val job2 = CoroutineScope(Dispatchers.Default).launch {
        delay(500)
        println("Job 2 terminé")
    }
    
    // Attendre la fin des deux coroutines
    job1.join()
    job2.join()
    
    println("Tous les jobs terminés")
    
  • Await : Attendre le résultat d'une opération asynchrone représentée par Deferred.

    // Opération asynchrone renvoyant un résultat
    val deferredResult = CoroutineScope(Dispatchers.Default).async {
        delay(1000)
        "Résultat de async"
    }
    
    // Attendre le résultat
    val result = deferredResult.await()
    println(result)
    
  • CoroutineScope.coroutineScope : Créer une nouvelle portée qui ne se terminera qu'après la fin de toutes les coroutines enfants. Utile pour la concurrence structurée.

    suspend fun doParallelWork() {
        coroutineScope { // Créer une nouvelle portée de concurrence structurée
            launch { delay(1000); println("Tâche 1 terminée") }
            launch { delay(500); println("Tâche 2 terminée") }
        } // Ce point ne sera atteint qu'après la fin des tâches 1 et 2
        println("Toutes les tâches parallèles terminées")
    }
    
  • Semantique des acteurs (Channel) : Pour l'échange de messages et la synchronisation d'accès aux données modifiables entre coroutines.

    // Créer un canal pour échanger des Int
    val channel = Channel<Int>()
    
    CoroutineScope(Dispatchers.Default).launch {
        // Envoyer des données dans le canal
        for (i in 1..5) {
            channel.send(i)
        }
        channel.close() // Fermer le canal après l'envoi
    }
    
    CoroutineScope(Dispatchers.Default).launch {
        // Recevoir des données du canal
        for (value in channel) {
            println("Reçu $value")
        }
    }
    
  • Mutex : Pour assurer un accès exclusif à une ressource partagée.

    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun incrementCounter() {
        mutex.withLock { // Acquérir le mutex
            counter++
            // Le mutex sera automatiquement libéré à la sortie du bloc
        }
    }
    

Le choix de la méthode dépend de ce qu'il faut synchroniser précisément : attendre la fin, obtenir un résultat, gérer des tâches parallèles, échanger des données ou un accès exclusif. coroutineScope est l'approche recommandée par défaut pour la concurrence structurée.