Processos que fazem muitas operações de I/O (chamadas HTTP, acesso a banco, leitura de arquivos) sofrem com o custo de criar e gerenciar threads “pesadas”. O Java 21 trouxe as Virtual Threads, que permitem rodar milhares de tarefas simultâneas com muito menos custo.
Explicação
Imagine um restaurante onde cada cliente tem um garçom exclusivo. Quando o garçom vai buscar a comida, o cliente fica esperando, e o garçom não pode atender outro cliente nesse tempo. Isso é como as threads tradicionais funcionam: cada uma espera por I/O e fica ociosa. Já com Virtual Threads, os garçons atendem vários clientes: enquanto um espera, o garçom pode servir outro.
Principais pontos:
- São threads de verdade, mas muito leves.
- Brilham em workloads de I/O (APIs, scraping, integrações).
- O código continua simples, com estilo síncrono (menos callbacks).
Exemplo Prático
Abaixo, criamos muitas tarefas simulando I/O com sleep. Usamos um executor que cria uma Virtual Thread por tarefa.
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class VirtualThreadsDemo {
public static void main(String[] args) {
// Cria um executor que abre uma Virtual Thread para cada tarefa submetida.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10).forEach(i ->
executor.submit(() -> {
try {
// Simula I/O (chamada externa, query etc.)
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Tarefa " + i + " rodou em " + Thread.currentThread());
})
);
// Fechar o executor aguarda a conclusão das tarefas.
}
}
}
Comparando o tempo
- Sem paralelismo (executando em sequência): cada tarefa espera 200 ms. Para 10 tarefas, o tempo total seria cerca de 2000 ms (2 segundos).
- Com Virtual Threads (executando em paralelo): todas as tarefas dormem ao mesmo tempo. O tempo total fica próximo de 200 ms, praticamente o custo da tarefa mais lenta.
Conclusão
Virtual Threads simplificam a escrita de código concorrente e escalam muito melhor para I/O. Use em serviços web, integrações e pipelines que esperam por recursos externos. Próximos passos: experimente no seu projeto, meça o throughput e, se estiver usando Spring Boot 3.2+, avalie habilitar threads virtuais no servidor para ganhar ainda mais desempenho.