0Pricing
Java Academy · Aula

ExecutorService e Tipos de Pools de Threads

Crie pools de threads fixos, em cache, unitários e agendados e compreenda quando usar cada um.

ExecutorService e Tipos de Pools de Threads é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

Por que usar pools de threads?

Criar uma nova Thread para cada tarefa é caro: a criação e a destruição de threads geram sobrecarga. Um pool de threads reutiliza um conjunto fixo de threads para executar muitas tarefas, reduzindo a sobrecarga e controlando o consumo de recursos.

import java.util.concurrent.*;

// Bad practice: new thread per task
new Thread(() -> System.out.println("task")).start();

// Better: reuse threads from a pool
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> System.out.println("task from pool"));
pool.shutdown();

newFixedThreadPool

Cria um pool com exatamente N threads. As tarefas adicionais entram em uma fila até que uma thread fique disponível. É uma boa opção quando você conhece o nível de paralelismo desejado.

ExecutorService pool = Executors.newFixedThreadPool(4);

for (int i = 0; i < 10; i++) {
    final int taskId = i;
    pool.submit(() -> {
        System.out.println("Task " + taskId + " on " + Thread.currentThread().getName());
    });
}

pool.shutdown();
pool.awaitTermination(10, TimeUnit.SECONDS);

newCachedThreadPool

Cria threads sob demanda e reutiliza as que estão ociosas. Threads ociosas por 60 segundos são encerradas. É uma boa opção para muitas tarefas de curta duração, mas é arriscado para tarefas de longa duração ou ilimitadas, pois pode esgotar a memória.

ExecutorService cached = Executors.newCachedThreadPool();

for (int i = 0; i < 100; i++) {
    cached.submit(() -> {
        // quick task
        double result = Math.sqrt(Math.random());
    });
}
cached.shutdown();

newSingleThreadExecutor

Um pool com exatamente uma thread. As tarefas são executadas sequencialmente, na ordem de envio. É uma boa opção para serializar o acesso a um recurso compartilhado.

ExecutorService single = Executors.newSingleThreadExecutor();

single.submit(() -> System.out.println("Task 1"));
single.submit(() -> System.out.println("Task 2"));
single.submit(() -> System.out.println("Task 3"));
// Always prints: Task 1, Task 2, Task 3 (sequential)
single.shutdown();

newScheduledThreadPool

Oferece suporte a tarefas agendadas e recorrentes. Use-o para consultas periódicas, novas tentativas e manutenção em segundo plano.

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

// One-shot delay
scheduler.schedule(() -> System.out.println("Delayed!"),
    3, TimeUnit.SECONDS);

// Fixed rate (every 2 seconds)
scheduler.scheduleAtFixedRate(
    () -> System.out.println("Tick"),
    0, 2, TimeUnit.SECONDS);

// Run later: scheduler.shutdown();

VirtualThreadExecutor (Java 21+)

O Java 21 introduz threads virtuais, que são leves e baratas de criar. Use Executors.newVirtualThreadPerTaskExecutor() para cargas de trabalho intensivas em E/S:

// Java 21+
try (var exec = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 10_000; i++) {
        final int id = i;
        exec.submit(() -> {
            Thread.sleep(100); // blocks without tying up OS thread
            System.out.println("vthread " + id);
        });
    }
} // auto-shutdown

Escolha do pool adequado

Diretrizes:

  • Tarefas limitadas pela CPU: pool fixo com N = número de núcleos da CPU
  • Tarefas limitadas por E/S: pool em cache ou threads virtuais
  • Tarefas sequenciais: executor de thread única
  • Tarefas agendadas/recorrentes: pool de threads agendadas
int cores = Runtime.getRuntime().availableProcessors();
ExecutorService cpuPool = Executors.newFixedThreadPool(cores);
System.out.println("Pool size: " + cores);

ThreadPoolExecutor personalizado

Para obter um controle detalhado, crie um ThreadPoolExecutor diretamente:

ThreadPoolExecutor tpe = new ThreadPoolExecutor(
    2,           // corePoolSize
    10,          // maximumPoolSize
    60L,         // keepAliveTime
    TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100), // work queue
    Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.CallerRunsPolicy() // rejection policy
);
tpe.submit(() -> System.out.println("Custom pool task"));
tpe.shutdown();

Encerramento adequado

Sempre encerre o ExecutorService para liberar as threads. shutdown() deixa de aceitar novas tarefas, mas conclui as que estão na fila. shutdownNow() tenta cancelar as tarefas em execução.

ExecutorService pool = Executors.newFixedThreadPool(4);
// ... submit tasks ...

pool.shutdown(); // no new tasks
try {
    if (!pool.awaitTermination(30, TimeUnit.SECONDS)) {
        pool.shutdownNow(); // force cancel
    }
} catch (InterruptedException e) {
    pool.shutdownNow();
    Thread.currentThread().interrupt();
}

ExecutorService como AutoCloseable (Java 19+)

No Java 19 e em versões posteriores, ExecutorService implementa AutoCloseable. Use try-with-resources para realizar o encerramento automaticamente:

// Java 19+ (preview), Java 21 stable
try (ExecutorService pool = Executors.newFixedThreadPool(4)) {
    pool.submit(() -> System.out.println("task"));
} // pool.close() called: waits for tasks then shuts down

Políticas de rejeição

Quando o pool está saturado, com todas as threads ocupadas e a fila cheia, a política de rejeição trata o excesso:

  • AbortPolicy (padrão): lança RejectedExecutionException
  • CallerRunsPolicy: a thread chamadora executa a tarefa
  • DiscardPolicy: descarta a tarefa silenciosamente
  • DiscardOldestPolicy: descarta a tarefa mais antiga da fila

Verificação rápida

Você tem uma tarefa limitada pela CPU que realiza uma computação pesada. Quantas threads o pool fixo deve ter?

Recapitulação: ExecutorService e pools de threads

Principais conclusões:

  • Pool fixo: N threads fixas; as tarefas adicionais entram na fila
  • Pool em cache: cresce sob demanda; as threads ociosas expiram após 60 segundos
  • Thread única: a ordem de execução sequencial é garantida
  • Pool agendado: tarefas atrasadas e recorrentes
  • Sempre chame shutdown(); use awaitTermination() para uma saída limpa

Perguntas Frequentes

A aula “ExecutorService e Tipos de Pools de Threads” é grátis?

Sim — o texto completo de “ExecutorService e Tipos de Pools de Threads” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “ExecutorService e Tipos de Pools de Threads”?

Crie pools de threads fixos, em cache, unitários e agendados e compreenda quando usar cada um. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “ExecutorService e Tipos de Pools de Threads”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. ExecutorService e Tipos de Pools de Threads
  2. Envio de Tarefas: Runnable versus Callable
  3. Future e Tratamento de Erros
  4. ScheduledExecutorService para Tarefas Recorrentes
← Voltar para Java Academy