---
title: "O que São Coroutines em Kotlin? | Kotlin Brasil"
url: "https://kotlin.dev.br/perguntas/o-que-sao-coroutines/"
markdown_url: "https://kotlin.dev.br/perguntas/o-que-sao-coroutines.MD"
description: "Aprenda o que são coroutines em Kotlin, como funcionam e por que são essenciais para programação assíncrona. Exemplos práticos inclusos."
date: "2026-01-19"
author: "Karina Melo"
---

# O que São Coroutines em Kotlin? | Kotlin Brasil

Aprenda o que são coroutines em Kotlin, como funcionam e por que são essenciais para programação assíncrona. Exemplos práticos inclusos.


## O que são coroutines em Kotlin?

Se você já estudou um pouco de Kotlin, com certeza já ouviu falar em **coroutines**. Esse é um dos recursos mais poderosos da linguagem, mas também um dos que mais gera dúvida. Bora desmistificar?

### Explicando de forma simples

Coroutines são uma forma de escrever **código assíncrono de maneira sequencial e legível**. Em vez de lidar com callbacks aninhados (o famoso "callback hell") ou com APIs complicadas de threads, você escreve código que parece síncrono, mas que por baixo dos panos não bloqueia a thread principal.

Pense assim: imagine que você está num restaurante. Em vez de ficar parado esperando o prato ficar pronto (bloqueando), você faz o pedido e vai fazer outra coisa enquanto a cozinha trabalha. Quando o prato fica pronto, você volta pra comer. É isso que uma coroutine faz com seu código.

### Um exemplo prático

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Começando o programa...")

    // Lança duas coroutines que rodam "ao mesmo tempo"
    val pedido1 = async { buscarDados("Usuários", 2000) }
    val pedido2 = async { buscarDados("Produtos", 1500) }

    // Espera os dois resultados
    println(pedido1.await())
    println(pedido2.await())

    println("Tudo pronto!")
}

suspend fun buscarDados(tipo: String, tempoMs: Long): String {
    delay(tempoMs)  // Simula uma operacao demorada (nao bloqueia a thread!)
    return "Dados de $tipo carregados com sucesso"
}
```

Nesse exemplo, as duas buscas acontecem **simultaneamente**, e o tempo total é determinado pela mais lenta (2 segundos), e não pela soma das duas (3,5 segundos). Isso faz uma diferença enorme em aplicações reais.

### Conceitos fundamentais

- **`suspend fun`**: marca uma função que pode ser suspensa e retomada sem bloquear a thread. Confira o [glossário de suspend](/glossario/suspend/) para entender melhor.
- **`launch`**: inicia uma coroutine sem esperar o resultado (tipo "dispara e esquece"). Veja mais no [glossário de launch](/glossario/launch/).
- **`async/await`**: inicia uma coroutine e permite aguardar o resultado depois. Detalhes no [glossário de async](/glossario/async/).
- **`runBlocking`**: cria um escopo de coroutine bloqueante, usado normalmente no `main` ou em testes
- **`delay`**: pausa a coroutine sem bloquear a thread (diferente de `Thread.sleep`)

### Coroutines vs. Threads: qual a diferença?

Essa comparação ajuda muito a entender o valor das coroutines. Threads são gerenciadas pelo sistema operacional e consomem recursos significativos -- cada thread precisa de sua própria pilha de memória (geralmente cerca de 1 MB). Já coroutines são gerenciadas pelo runtime do Kotlin e são extremamente leves.

Para ilustrar, veja a diferença na prática:

```kotlin
import kotlinx.coroutines.*

// Com coroutines: roda 100.000 sem problemas
fun main() = runBlocking {
    val tarefas = List(100_000) {
        launch {
            delay(1000)
            print(".")
        }
    }
    tarefas.forEach { it.join() }
    println("\nTodas as coroutines terminaram!")
}
```

Tentar criar 100.000 threads tradicionais provavelmente causaria um `OutOfMemoryError`. Já com coroutines, isso roda de boas porque elas compartilham um pool pequeno de threads por baixo dos panos.

Outra diferença importante: threads usam **preemptive multitasking** (o sistema operacional decide quando pausar), enquanto coroutines usam **cooperative multitasking** (a coroutine decide quando ceder o controle, nos pontos de suspensão). Isso torna o comportamento mais previsível.

### Dispatchers: onde a coroutine executa

Os [dispatchers](/glossario/dispatcher/) definem em qual thread ou pool de threads a coroutine vai rodar. Escolher o dispatcher correto é essencial:

```kotlin
import kotlinx.coroutines.*

suspend fun exemploDispatchers() {
    // Para operacoes de CPU (processamento pesado)
    withContext(Dispatchers.Default) {
        // Calculos complexos, ordenacao, etc.
    }

    // Para operacoes de I/O (rede, banco de dados, arquivos)
    withContext(Dispatchers.IO) {
        // Chamadas de API, leitura de arquivos, queries no banco
    }

    // Para atualizar a UI (Android)
    withContext(Dispatchers.Main) {
        // Atualizar textos, mostrar dados na tela
    }
}
```

Usar `Dispatchers.IO` para chamadas de rede e `Dispatchers.Default` para processamento pesado evita que a thread principal fique bloqueada. No Android, isso é obrigatório para manter o app responsivo.

### Quando usar coroutines?

Coroutines brilham em cenários como:

- **Chamadas de API**: buscar dados de um servidor sem congelar a interface do app
- **Acesso a banco de dados**: consultas ao [Room](/tutoriais/kotlin-room-database-tutorial/) ou outros bancos locais
- **Operações paralelas**: quando você precisa fazer várias coisas ao mesmo tempo e combinar os resultados
- **Tarefas em background**: processamento de imagens, sincronização de dados, uploads
- **Streams de dados**: combinadas com [Flow](/glossario/flow/), permitem trabalhar com fluxos de dados reativos. Veja nosso [tutorial de Kotlin Flow](/tutoriais/kotlin-flow-tutorial/) e o [guia completo de coroutines](/guias/guia-coroutines-completo/).

### Structured Concurrency: coroutines organizadas

Um conceito central em Kotlin é a **concorrência estruturada**. Toda coroutine precisa ser lançada dentro de um [escopo](/glossario/scope/) (CoroutineScope), e esse escopo controla o ciclo de vida de todas as coroutines filhas. Se o escopo for cancelado, todas as coroutines dentro dele também são canceladas automaticamente.

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        launch { tarefaA() }
        launch { tarefaB() }
        // Se esse escopo for cancelado, tarefaA e tarefaB tambem sao
    }

    delay(500)
    job.cancel() // Cancela tudo de uma vez
    println("Tarefas canceladas")
}

suspend fun tarefaA() {
    repeat(10) {
        delay(200)
        println("Tarefa A: passo $it")
    }
}

suspend fun tarefaB() {
    repeat(10) {
        delay(300)
        println("Tarefa B: passo $it")
    }
}
```

Para entender melhor como escopos e [jobs](/glossario/job/) funcionam juntos, confira o [tutorial avançado de coroutines](/tutoriais/coroutines-avancado/).

### Por que coroutines são tão importantes?

No desenvolvimento Android, a thread principal (UI thread) não pode ser bloqueada, senão o app trava. Coroutines resolvem isso de forma elegante, permitindo que operações pesadas como chamadas de API e acesso a banco de dados rodem sem congelar a interface. No Android, os escopos mais usados são `viewModelScope` e `lifecycleScope`, que se integram com o [ViewModel](/glossario/viewmodel/) e o ciclo de vida dos componentes.

No backend, coroutines permitem que um servidor atenda **milhares de requisições simultâneas** com muito menos recursos do que seria necessário usando threads tradicionais. Frameworks como [Ktor](/guias/guia-kotlin-backend-ktor/) foram construídos em cima de coroutines, e até o [Spring Boot com Kotlin](/guias/guia-kotlin-backend-spring/) oferece suporte nativo.

### O principal cuidado

Coroutines são leves, mas não são mágicas. É importante entender os **escopos e o ciclo de vida** de cada coroutine pra evitar vazamentos de memória e comportamentos inesperados. No Android, por exemplo, use `viewModelScope` ou `lifecycleScope` em vez de criar escopos soltos.

Outro cuidado comum: nunca use `runBlocking` dentro de uma coroutine. Ele bloqueia a thread atual e pode causar deadlocks. Reserve o `runBlocking` para o `main()` e para testes unitários.

Dominar coroutines leva um tempinho, mas é um investimento que vale muito a pena. É um daqueles conhecimentos que transformam a forma como você programa. Para ir mais fundo, comece pelo [tutorial básico de coroutines](/tutoriais/coroutines-tutorial-básico/) e depois avance para o [guia completo](/guias/guia-coroutines-completo/).
