Threads

Hello World 😁 💻

Hoje vamos abordar um conceito importantíssimo na computação, muito falado e repetido, mas que nem sempre é compreendido de fato: Threads.

Mas afinal, o que são Threads?

Uma thread é uma linha de execução dentro de um programa. Todo programa em execução é um processo, e dentro dele podem existir múltiplas threads. Elas permitem dividir a execução em partes menores, que podem rodar de forma concorrente, ou seja, quase ao mesmo tempo, dentro do mesmo processo.

Um processo pode ter apenas uma thread, caracterizando uma execução simples e linear, ou várias threads, permitindo concorrência.

Como as Threads funcionam?

Um único processo pode conter várias threads trabalhando em conjunto. Elas dividem a carga de trabalho e permitem que diferentes partes do programa avancem simultaneamente.

Diferente dos processos, que são isolados entre si, as threads de um mesmo processo compartilham o mesmo espaço de memória, arquivos abertos e variáveis globais. Isso torna a comunicação entre elas muito mais rápida.

Ao mesmo tempo, cada thread mantém seu próprio contexto de execução. Isso inclui o contador de programa, que indica qual instrução será executada a seguir, além de registradores e uma pilha própria (stack).

Para facilitar a visualização, pense em um navegador como o Google Chrome. Ele pode carregar uma página, tocar um vídeo, baixar um arquivo e executar JavaScript ao mesmo tempo. Cada uma dessas tarefas pode estar rodando em uma thread diferente.

Por que usamos Threads?

O uso de threads está diretamente ligado a desempenho e experiência do usuário.

Em termos de responsividade, elas permitem que uma aplicação continue reagindo enquanto executa tarefas demoradas. Em um software com interface gráfica, por exemplo, uma thread pode cuidar da renderização da tela enquanto outra realiza uma requisição ao banco de dados ou baixa um arquivo. Isso evita que o programa “trave”.

Além disso, há o aproveitamento de hardware. Processadores modernos possuem múltiplos núcleos, e as threads permitem que o sistema operacional distribua o trabalho entre eles, executando tarefas de forma realmente paralela.

Outro ponto importante é o custo. Criar e alternar entre threads é mais leve e rápido do que trabalhar com múltiplos processos.

O desafio da concorrência

Esse modelo, apesar de poderoso, traz um problema clássico.

Como as threads compartilham memória, pode acontecer de duas ou mais tentarem acessar ou modificar o mesmo dado ao mesmo tempo. Sem controle, isso leva a comportamentos imprevisíveis.

Esse tipo de situação é conhecido como condição de corrida (race condition), onde o resultado final depende da ordem de execução das threads, algo que não é determinístico.

Para lidar com isso, utilizamos mecanismos de sincronização, como mutexes (locks), que funcionam como um cadeado garantindo acesso exclusivo a um recurso, e semáforos, que controlam o acesso a recursos limitados.

Em Java, por exemplo, threads podem ser criadas utilizando classes como Thread, interfaces como Runnable ou abstrações mais modernas como ExecutorService.

Nesse contexto, existe também o Java Memory Model (JMM), que define como as threads interagem com a memória, estabelecendo regras sobre visibilidade e ordenação das operações em cenários concorrentes.

Um paralelo simples

Para tornar isso mais intuitivo, podemos imaginar um restaurante.

O processo seria o restaurante em si, com sua cozinha, mesas e estoque. As threads seriam os funcionários, como o garçom, o cozinheiro e o faxineiro.

Todos compartilham o mesmo ambiente e os mesmos recursos. Enquanto o garçom anota um pedido, o cozinheiro pode estar preparando um prato.

Mas se todos tentarem usar o mesmo fogão ao mesmo tempo, sem organização, surgem conflitos. É aí que entra a necessidade de coordenação, equivalente à sincronização no software.

Exemplo prático

Agora vamos observar isso na prática analisando o comportamento do Google Chrome.

Primeiro, podemos listar os processos do navegador com:

ps -C chrome

Comando para ver os processos no Chrome.

Lista de processos do Chrome no terminal.

Cada linha representa um processo, identificado pelo seu PID.

Para visualizar as threads dentro desses processos, usamos:

ps -fL -C chrome

Comando para ver as threads dos processos no Chrome.

Lista das threads dos processos no Chrome

Considere o seguinte trecho:

 PID PPID   LWP  NLWP
3998 3029  3998   38
3998 3029  4019   38
3998 3029  4033   38

Aqui temos um único processo (PID 3998) com 38 threads no total. Cada linha representa uma thread diferente, identificada pelo LWP.

Agora observe outro trecho:

4015 3998 4015 1
4016 3998 4016 1
4018 4016 4018 1

Nesse caso, cada processo possui apenas uma thread. Isso mostra que o Chrome combina processos maiores, com múltiplas threads, e processos menores, mais simples.

Essa organização forma uma hierarquia. O processo principal cria processos filhos conforme necessário, distribuindo responsabilidades. Algumas tarefas exigem mais threads, como abas com conteúdo pesado, enquanto outras são mais leves.

O que estamos vendo, na prática, não é um único programa rodando, mas um conjunto de processos, cada um com suas próprias threads, organizados e executados simultaneamente.

No nível do sistema operacional, especialmente no Linux, o escalonador trabalha diretamente com threads. Ele decide qual delas será executada, por quanto tempo e com qual prioridade.

Conclusão

As threads são a base que permite a execução concorrente dentro de um programa. Elas compartilham recursos, reduzem custos e aumentam a eficiência, mas exigem cuidado na coordenação para evitar erros difíceis de detectar.

Mais do que um único fluxo linear, o que realmente acontece em um sistema moderno é a execução dinâmica de múltiplas threads, de diferentes processos, sendo gerenciadas constantemente pelo sistema operacional.

É isso que torna possível ouvir música, navegar na internet, assistir a vídeos e executar diversas tarefas ao mesmo tempo sem que o computador pareça sobrecarregado.

Se você chegou até aqui, espero que esse conteúdo tenha ajudado a esclarecer melhor esse conceito tão importante.

Obrigada pela atenção e até breve. 😁

Laryssa Ramos

Voltar para os artigos