Como Funciona o Algoritmo Threads: o “Cérebro” por trás da Programação Concorrente
Como funciona o algoritmo Threads (Threading): entenda a magia da execução simultânea
O que são threads?
Por que usar threads?
“Algoritmo de threads” não é uma receita única
2) Submeter trabalho a elas (funções/callbacks).
3) Coordenar acesso a recursos compartilhados.
4) Sincronizar progresso e término.
5) Tratar falhas e garantir encerramento correto.
Visão geral: quem controla a execução?
• Camada do sistema operacional: gerencia threads do processo e decide quando cada uma recebe CPU.
O escalonador: como o SO decide quem executa
Estados de uma thread: de “nascida” a “finalizada”
• Ready (pronta): aguardando CPU.
• Running (em execução): efetivamente rodando.
• Waiting/Blocked (bloqueada): esperando por algo (I/O, lock, semáforo).
• Terminated (encerrada): finalizou a tarefa.
Concorrência vs Paralelismo: entenda a diferença
• Paralelismo: várias tarefas rodam simultaneamente, de verdade, em múltiplos núcleos.
Sincronização: o coração do “algoritmo threads”
Mutex (mutex/lock): exclusão mútua
Semáforo: controle de acesso por contagem
Condição (condition variables): esperar e notificar
Barreiras e joins: esperar pontos específicos
• barreira: esperar um grupo de threads chegar a um “marco” antes de continuar.
Thread-safe: o que significa de verdade?
• estruturas de dados concorrentes;
• imutabilidade (se ninguém altera, fica mais fácil);
• confinamento (cada thread com seu próprio estado);
• atomics (operações indivisíveis).
Problemas clássicos em programação com threads
1) Condição de corrida (Race Condition)
2) Deadlock
3) Starvation (Fome)
4) Livelock
Arquitetura recomendada: use um padrão
• Thread Pool: em vez de criar uma thread por tarefa, mantém um conjunto fixo para reaproveitar.
• Async + Threads: para I/O, às vezes vale usar modelo assíncrono; para CPU pesada, threads/paralelismo.
Thread Pool: por que ele costuma ser melhor
Boas práticas para escrever código com threads com confiança
Se uma variável é global (ou compartilhada por referência), trate como potencialmente concorrida.
Defina qual condição deve ser verdadeira sempre (por exemplo: “a fila nunca fica negativa” ou “o contador sempre reflete o total processado”).
Trave, atualize o estado mínimo e destrave. Quanto maior o trecho protegido, maior a contenção.
Bibliotecas geralmente implementam padrões corretamente.
Concorrência é sensível a timing. Use testes com muitos ciclos e entradas diferentes.
Race detectors e análise estática ajudam a encontrar problemas antes de produção.
Threads em diferentes contextos: da CPU ao servidor
Threads em aplicações desktop
Threads em servidores web
Threads e I/O: nem sempre é a melhor escolha
Conclusão: entendendo o algoritmo threads por dentro
• o sistema operacional decide quando cada thread roda
• a aplicação sincroniza acesso a recursos compartilhados
• o programa coordena progresso e finalização (join/barreiras)
• evitamos armadilhas como race conditions, deadlocks e starvation







