Sobes.tech
Middle

Quels éléments de multitâche Kotlin fournit-il?

sobes.tech IA

Réponse de l'IA

Kotlin fournit les éléments de concurrence suivants :

  • Coroutines : Fils légers basés sur des fonctions suspendues. Permettent une exécution asynchrone et non bloquante du code.
  • Constructeurs de coroutines : Fonctions qui démarrent des coroutines. Principaux : launch (démarre une coroutine sans retourner de valeur), async (démarre une coroutine et retourne un Deferred qui peut être attendu pour obtenir le résultat).
    // Exemple d'utilisation de launch
    GlobalScope.launch {
        println("Bonjour depuis la coroutine ${Thread.currentThread().name}")
    }
    
    // Exemple d'utilisation de async
    val deferred = GlobalScope.async {
        delay(1000) // Simule une opération longue
        "Résultat"
    }
    val result = runBlocking { deferred.await() } // Attend le résultat
    
  • Dispatchers : Définissent le pool de threads sur lequel la coroutine sera exécutée. Principaux :
    • Dispatchers.Default : Pool général pour les tâches intensives en CPU.
    • Dispatchers.IO : Pool pour les opérations d'entrée/sortie bloquantes (fichiers, réseau).
    • Dispatchers.Main : Dispatcher pour le thread de l'interface utilisateur sur les plateformes appropriées (Android, Swing).
    • Dispatchers.Unconfined : La coroutine démarre dans le thread actuel mais peut être reprise dans n'importe quel thread.
    GlobalScope.launch(Dispatchers.IO) {
        // Exécution d'entrée/sortie
    }
    
  • runBlocking : Fonction constructeur de coroutine qui bloque le thread actuel jusqu'à ce que la coroutine se termine. Utilisée pour combiner du code bloquant et non bloquant, souvent dans les tests ou les fonctions main.
    runBlocking {
        launch {
            delay(500)
            println("Terminé dans ${Thread.currentThread().name}")
        }
        println("Lancé dans ${Thread.currentThread().name}")
    }
    
  • Fonctions suspend : Fonctions dont l'exécution peut être suspendue et reprise. Ne peuvent être appelées que depuis d'autres fonctions suspend ou constructeurs de coroutines.
    suspend fun doSomething() {
        delay(100) // Exemple de suspension
    }
    
  • Job : Handle pour une coroutine en cours d'exécution. Fournit des méthodes pour gérer le cycle de vie de la coroutine (annulation, attente de fin).
    val job = GlobalScope.launch {
       // Opération longue
    }
    job.cancel() // Annule la coroutine
    runBlocking { job.join() } // Attend la fin
    
  • CoroutineScope : Définit une portée pour les coroutines. Les coroutines lancées dans une portée spécifique sont automatiquement annulées lors de l'annulation de la portée. Aide à gérer le cycle de vie des coroutines.
    val scope = CoroutineScope(Dispatchers.Default)
    scope.launch {
        // Coroutine dans cette portée
    }
    scope.cancel() // Annule toutes les coroutines dans cette portée
    
  • Canaux (Channel) : Primitive pour la transmission sécurisée de données entre coroutines. Les canaux peuvent être unidirectionnels (envoi ou réception uniquement) ou bidirectionnels.
    import kotlinx.coroutines.channels.Channel
    
    val channel = Channel<Int>()
    
    runBlocking {
        launch {
            for (x in 1..5) channel.send(x * x)
            channel.close() // Important de fermer le canal
        }
        launch {
            for (y in channel) println(y)
        }
    }
    
  • Mutex (Mutex) : Primitive de synchronisation pour assurer un accès exclusif à une ressource partagée. Garantit la sécurité des threads, permettant à une seule coroutine de posséder le mutex à un moment donné.
    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun incrementCounter() {
        mutex.withLock {
            counter++
        }
    }
    
  • États (StateFlow, SharedFlow) : Primitive pour travailler avec des flux de données dans le contexte de la programmation réactive et de la concurrence. StateFlow représente un flux "froid" avec l'état actuel, et SharedFlow un flux "chaud" pour la diffusion de données.