Concorrência e Multithreading em Kotlin: Nível Avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Concorrência e Multithreading em Kotlin: Nível Avançado

\n

No desenvolvimento moderno com Kotlin, especialmente para aplicações server-side e Android, o gerenciamento adequado de concorrência é a chave para desempenho e responsividade. No nível avançado, não basta apenas iniciar uma corrotina. É necessário entender como sincronizar eficientemente o acesso a dados, gerenciar threads e evitar bloqueios "infernais". Neste artigo, abordaremos técnicas avançadas: desde os detalhes de kotlinx.coroutines até coleções thread-safe e canais.

\n\n

1. Mergulho Profundo em Corrotinas: Structured Concurrency e Scopes

\n

A base do trabalho avançado é a Structured Concurrency. Este é o princípio onde o ciclo de vida de uma corrotina está vinculado a um escopo (scope). Se a corrotina pai for cancelada, todas as suas tarefas filhas são automaticamente encerradas. Isso evita vazamentos de memória e processos incontroláveis.

\n

No nível avançado, você deve criar seus próprios scopes, em vez de depender do GlobalScope global.

\n\n
import kotlinx.coroutines.*\nimport kotlin.coroutines.CoroutineContext\n\nclass DataRepository {\n    // Scope próprio com dispatcher e manipulador de exceções\n    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler { _, throwable ->\n        println("Erro não tratado: ${throwable.message}")\n    })\n\n    fun loadData() {\n        scope.launch {\n            // corrotinas filhas\n            val data = async { fetchFromNetwork() }\n            val cache = async { loadFromCache() }\n            process(data.await(), cache.await())\n        }\n    }\n\n    fun cleanup() {\n        scope.cancel() // cancela todas as corrotinas no escopo\n    }\n}
\n\n

Use SupervisorJob quando a falha de uma corrotina filha não deve cancelar as demais. Isso é crítico para camadas de UI ou requisições paralelas independentes.

\n\n

2. Coleções Thread-Safe e Operações Atômicas

\n

Mesmo com corrotinas, se você trabalha com dados mutáveis compartilhados, a sincronização é necessária. Kotlin oferece várias abordagens:

\n
    \n
  • Tipos atômicos (AtomicInteger, AtomicReference) — para contadores e flags simples.
  • \n
  • Coleções Thread-Safe (ConcurrentHashMap, CopyOnWriteArrayList) — para estruturas complexas.
  • \n
  • Mutex do kotlinx.coroutines — para seções críticas dentro de corrotinas.
  • \n
\n\n
import kotlinx.coroutines.*\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport java.util.concurrent.ConcurrentHashMap\nimport java.util.concurrent.atomic.AtomicInteger\n\nclass SafeCounter {\n    private val mutex = Mutex()\n    private var counter = 0\n\n    suspend fun increment() {\n        mutex.withLock {\n            counter++ // seção crítica\n        }\n    }\n\n    fun getCounter(): Int = counter\n}\n\nclass CacheManager {\n    private val cache = ConcurrentHashMap<String, String>()\n    private val hitCount = AtomicInteger(0)\n\n    fun put(key: String, value: String) {\n        cache[key] = value\n    }\n\n    fun get(key: String): String? {\n        val result = cache[key]\n        if (result != null) hitCount.incrementAndGet()\n        return result\n    }\n}
\n\n

Importante: Mutex é uma função suspend, portanto não bloqueia a thread, mas suspende a corrotina. Isso é mais eficiente que synchronized.

\n\n

3. Canais (Channels) e Flow: Fluxos de Dados Reativos

\n

Para transferir dados entre corrotinas, use Channels (análogo ao BlockingQueue para corrotinas) e Flow (fluxo assíncrono frio).

\n\n

Canais: Producer-Consumer

\n
import kotlinx.coroutines.channels.*\nimport kotlinx.coroutines.*\n\nfun Corout                

Blogs

Book Recommendations