Filas de Tarefas em Java: ExecutorService e ThreadPoolExecutor

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Filas de Tarefas em Java: ExecutorService e ThreadPoolExecutor



Em aplicações multithread em Java, o gerenciamento de tarefas e sua execução é uma das principais tarefas. Em vez de criar uma nova thread para cada tarefa (o que é caro e ineficiente), os desenvolvedores usam filas de tarefas (Task Queues) em combinação com pools de threads. Isso permite controlar o número de threads em execução simultânea, reutilizá-las e lidar suavemente com picos de carga.



A base para trabalhar com filas de tarefas em Java é o framework java.util.concurrent, introduzido no Java 5. Os principais componentes são: ExecutorService, ThreadPoolExecutor e várias implementações de BlockingQueue.



1. ExecutorService — Interface de alto nível



ExecutorService é uma interface que fornece métodos para execução assíncrona de tarefas. Ela oculta os detalhes do gerenciamento de threads. A maneira mais popular de obter uma instância é usar os métodos de fábrica da classe Executors:



ExecutorService executor = Executors.newFixedThreadPool(4); // pool de 4 threadsexecutor.submit(() -> {    System.out.println("Tarefa executando na thread: " + Thread.currentThread().getName());});executor.shutdown(); // finaliza após a execução de todas as tarefas


No entanto, os métodos de fábrica têm capacidades de configuração limitadas. Para ajustes finos, usa-se ThreadPoolExecutor diretamente.



2. ThreadPoolExecutor — Pool de threads configurável



ThreadPoolExecutor é o núcleo do framework. Ele aceita uma fila de tarefas, política de saturação, tempo de vida das threads e outros parâmetros. O construtor completo:



public ThreadPoolExecutor(    int corePoolSize,      // número mínimo de threads    int maximumPoolSize,   // número máximo de threads    long keepAliveTime,    // tempo de inatividade da thread antes da remoção    TimeUnit unit,         // unidade de tempo    BlockingQueue<Runnable> workQueue, // fila de tarefas    RejectedExecutionHandler handler   // política para quando a fila está cheia);


Exemplo de criação de um pool com fila personalizada:



BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);ThreadPoolExecutor executor = new ThreadPoolExecutor(    2, 4,    30, TimeUnit.SECONDS,    queue,    new ThreadPoolExecutor.AbortPolicy() // padrão — lança exceção);executor.execute(() -> {    // tarefa pesada});executor.shutdown();


3. BlockingQueue — Base da fila de tarefas



O tipo de fila determina como as tarefas serão armazenadas e transmitidas às threads. As implementações mais populares:

  • LinkedBlockingQueue — fila ilimitada baseada em lista encadeada. Se a capacidade não for definida, pode causar estouro de memória.
  • ArrayBlockingQueue — fila limitada baseada em array. Permite controlar o número de tarefas em espera.
  • SynchronousQueue — fila de capacidade zero. Cada tarefa é passada diretamente para uma thread, sem espera na fila.
  • PriorityBlockingQueue — fila com prioridades. As tarefas são ordenadas por prioridade (implementam Comparable).


Exemplo com fila limitada e política de rejeição:



BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);ThreadPoolExecutor executor = new ThreadPoolExecutor(    2, 5,    10, TimeUnit.SECONDS,    queue,    new ThreadPoolExecutor.CallerRunsPolicy() // tarefa executada na thread chamadora);for (int i = 0; i < 20; i++) {    executor.submit(() -> {        Thread.sleep(100);        return Math.random();    });}executor.shutdown();


4. Políticas de saturação (RejectedExecutionHandler)



Quando a fila está ch

Recommendations