Sobes.tech
Middle

Quais elementos de multitarefa o Kotlin fornece?

sobes.tech IA

Resposta da IA

O Kotlin fornece os seguintes elementos de concorrência:

  • Coroutines: Fios leves baseados em funções suspensas. Permitem a execução assíncrona e não bloqueante do código.
  • Construtores de coroutines: Funções que iniciam coroutines. Principais: launch (inicia uma coroutine sem retornar valor), async (inicia uma coroutine e retorna um Deferred, que pode ser esperado para obter o resultado).
    // Exemplo de uso de launch
    GlobalScope.launch {
        println("Olá da coroutine ${Thread.currentThread().name}")
    }
    
    // Exemplo de uso de async
    val deferred = GlobalScope.async {
        delay(1000) // Simula uma operação longa
        "Resultado"
    }
    val result = runBlocking { deferred.await() } // Espera o resultado
    
  • Dispatchers: Determinam em qual pool de threads a coroutine será executada. Principais:
    • Dispatchers.Default: Pool geral para tarefas intensivas em CPU.
    • Dispatchers.IO: Pool para operações de entrada/saída bloqueantes (arquivos, rede).
    • Dispatchers.Main: Dispatcher para a thread de interface do usuário em plataformas apropriadas (Android, Swing).
    • Dispatchers.Unconfined: A coroutine inicia na thread atual, mas pode ser retomada em qualquer thread.
    GlobalScope.launch(Dispatchers.IO) {
        // Execução de entrada/saída
    }
    
  • runBlocking: Função construtora de coroutine que bloqueia a thread atual até que a coroutine termine. Usada para combinar código bloqueante e não bloqueante, frequentemente em testes ou funções main.
    runBlocking {
        launch {
            delay(500)
            println("Concluído em ${Thread.currentThread().name}")
        }
        println("Iniciado em ${Thread.currentThread().name}")
    }
    
  • Funções suspend: Funções cujo execução pode ser suspensa e retomada. Só podem ser chamadas de outras funções suspend ou construtores de coroutines.
    suspend fun doSomething() {
        delay(100) // Exemplo de suspensão
    }
    
  • Job: Handle para uma coroutine em execução. Fornece métodos para gerenciar o ciclo de vida da coroutine (cancelar, esperar terminar).
    val job = GlobalScope.launch {
       // Operação longa
    }
    job.cancel() // Cancela a coroutine
    runBlocking { job.join() } // Espera terminar
    
  • CoroutineScope: Define um escopo para as coroutines. As coroutines lançadas em um escopo específico são automaticamente canceladas ao cancelar o escopo. Ajuda a gerenciar o ciclo de vida das coroutines.
    val scope = CoroutineScope(Dispatchers.Default)
    scope.launch {
        // Coroutine neste escopo
    }
    scope.cancel() // Cancela todas as coroutines neste escopo
    
  • Canais (Channel): Primitive para transmissão segura de dados entre coroutines. Os canais podem ser unidirecionais (apenas enviar ou receber) ou bidirecionais.
    import kotlinx.coroutines.channels.Channel
    
    val channel = Channel<Int>()
    
    runBlocking {
        launch {
            for (x in 1..5) channel.send(x * x)
            channel.close() // Importante fechar o canal
        }
        launch {
            for (y in channel) println(y)
        }
    }
    
  • Mutex (Mutex): Primitive de sincronização para garantir acesso exclusivo a um recurso compartilhado. Garantem segurança de thread, permitindo que apenas uma coroutine possua o mutex em um momento.
    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun incrementCounter() {
        mutex.withLock {
            counter++
        }
    }
    
  • Estados (StateFlow, SharedFlow): Primitive para trabalhar com fluxos de dados no contexto de programação reativa e concorrência. StateFlow representa um fluxo "frio" com o estado atual, e SharedFlow um fluxo "quente" para transmissão de dados.