Kotlin vs Python: quem vence? A batalha pela concorrência
\n\nSe você está lendo este material no PythonLib, provavelmente já conhece o Python e seu GIL (Global Interpreter Lock), que transforma o multithreading em uma dor de cabeça. Você escreve threading, espera um ganho de velocidade, e obtém… código síncrono com um toque de bloqueios. Familiar?
Bem-vindo ao mundo do Kotlin! Esta é uma linguagem que decidiu: "Vamos tornar a concorrência conveniente, rápida e sem dor". Neste artigo, vamos analisar três abordagens para concorrência em Kotlin: threads clássicas, corrotinas modernas e o poderoso duo async/await. Você aprenderá a escrever código assíncrono que não explode a mente e por que o Kotlin é uma excelente escolha para desenvolvimento backend e Android.
1. Threads em Kotlin: um velho amigo é melhor que dois novos?
\n\nVamos começar pelo básico. Threads em Kotlin são as mesmas threads do Java. Kotlin roda na JVM, então você tem acesso a todo o poder de java.lang.Thread. Mas sejamos honestos: threads são como dirigir um carro sem airbags. Funciona, mas é assustador.
Como criar uma thread em Kotlin?
\n\nA maneira mais simples:
\n\nfun main() {\n thread {\n println("Olá da thread: ${Thread.currentThread().name}")\n }\n println("Thread principal: ${Thread.currentThread().name}")\n}\n\nParece familiar, certo? Mas há um detalhe: threads são pesadas. Cada thread é um recurso separado do sistema. Se você criar 10.000 threads, seu programa ou travará com OutOfMemoryError, ou ficará lento como um computador antigo com Windows 95.
Problemas com threads:
\n- \n
- Alto consumo de memória — cada thread reserva uma pilha (~1 MB). \n
- Complexidade de sincronização — bloqueios, deadlocks, race conditions. Lembre-se de
synchronizedem Java e chore. \n - Troca de contexto — o SO gasta tempo alternando entre threads. \n
Para projetos pequenos, threads servem. Mas se você está construindo um serviço de alta carga ou uma aplicação com milhares de tarefas paralelas, é hora de olhar para as corrotinas.
\n\n2. Corrotinas em Kotlin: leves como uma pluma
\n\nCorrotinas são "threads turbinadas". Elas não estão vinculadas a threads do sistema e podem ser executadas em uma única thread, alternando entre tarefas sem a participação do SO. Parece complicado? Na prática, é simples e elegante.
\n\nPrimeira corrotina
\n\nPara trabalhar com corrotinas, você precisará da dependência kotlinx-coroutines-core. Mas se você usa Kotlin 1.3+, ela já está embutida.
import kotlinx.coroutines.*\n\nfun main() = runBlocking {\n launch {\n delay(1000L)\n println("Mundo após o atraso!")\n }\n println("Olá,")\n}\n\nO que está acontecendo aqui?
\n- \n
runBlocking— bloqueia a thread principal até que todas as corrotinas internas terminem. Para aprendizado, ok; para produção, use com cuidado. \n launch— inicia uma nova corrotina. Ela não bloqueia a thread, apenas pausa nodelay. \n delay— análogo aThread.sleep(), mas não bloqueante. A corrotina simplesmente "dorme" e libera a thread para outras tarefas. \n
Resultado: primeiro é exibido "Olá,", e após um segundo — "Mundo após o atraso!". Sem bloqueios, sem threads extras.
\n\nPor que corrotinas são melhores que threads?
\n- \n
- Leveza — um milhão de corrotinas? Fácil! Elas não criam threads separadas. \n
- Suspensão — uma corrotina pode parar a qualquer momento e continuar depois. \n
- Concorrência estruturada — corrotinas vivem em um escopo e são automaticamente canceladas se o escopo for encerrado. \n