O que é uma coroutine em Kotlin e como ela funciona?
sobes.tech IA
Resposta da IA
A coroutine em Kotlin é uma unidade leve de execução que permite escrever código assíncrono e não bloqueante de forma mais legível e sequencial. É semelhante a uma thread, mas muito mais leve e pode ser criada em grande quantidade.
Componentes principais e princípios de funcionamento:
- Funções Suspendidas (Funções Suspend): Funções marcadas com a palavra-chave
suspend, que podem suspender sua execução sem bloquear a thread em que estão sendo executadas. Quando uma função suspensa termina sua operação de "espera" (por exemplo, uma requisição de rede), ela pode retomar a execução de onde foi suspensa. - Contexto (Contexto de Coroutine): Conjunto de elementos que controlam o comportamento da coroutine. Inclui:
Job: Descritor da coroutine, que permite gerenciar seu ciclo de vida (cancelamento, espera por término).CoroutineDispatcher: Define o(s) thread(s) em que a coroutine será executada. Permite alternar entre threads.CoroutineName: Nome opcional para depuração.CoroutineExceptionHandler: Manipulador de exceções não tratadas.
- Construtores (Builders): Funções que iniciam a execução de coroutines:
launch: Inicia uma nova coroutine sem retornar resultado. Retorna umJob.async: Inicia uma nova coroutine que retorna um resultado (Deferred). Para obter o resultado, usa-se.await().runBlocking: Construtor bloqueante, usado principalmente para testes ou integração com código bloqueante.
Como funciona nos bastidores:
As coroutines não criam threads separadas para cada tarefa. Em vez disso, quando uma função suspend é suspensa, o compilador gera código que salva o estado atual dos cálculos. Quando o resultado está disponível, a coroutine é retomada em um dos threads gerenciados por CoroutineDispatcher. Isso é feito transformando funções suspend em chamadas assíncronas com continuations, permitindo que um único thread execute múltiplas coroutines, alternando entre elas quando suspensas.
Exemplo:
import kotlinx.coroutines.*
fun main() = runBlocking { // Bloqueia o thread atual até que a coroutine dentro de runBlocking termine
println("Primeiro")
launch { // Inicia uma nova coroutine em segundo plano
delay(1000L) // Atraso não bloqueante de 1 segundo
println("Após o atraso")
}
println("Depois") // Esta linha será executada antes de a coroutine launch terminar
}
A saída deste código será:
Primeiro
Depois
Após o atraso
Isso demonstra a natureza não bloqueante de launch e delay.