Filas de tarefas em Java: transformando caos em ordem

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

Quando seu código começa a gaguejar: introdução a filas e tarefas em segundo plano em Java

\n\n

Imagine a situação: você inicia um servidor web em Java. Chega uma requisição de um usuário — é necessário enviar um e-mail, gerar um relatório em PDF e atualizar as estatísticas. Se tudo for executado de forma síncrona, o usuário esperará 30 segundos. O café dele esfriará, e ele irá para a concorrência. Familiar?

\n\n

No mundo das tarefas em segundo plano em Java, isso é resolvido de forma elegante: colocamos a tarefa em uma fila e retornamos "200 OK" para o usuário. Depois, em segundo plano, nosso worker processa calmamente os e-mails, PDFs e estatísticas. Nada de caos, apenas ordem.

\n\n

Hoje, vamos explorar como implementar filas de tarefas em Java — desde a opção mais simples de thread única até soluções industriais com RabbitMQ e Kafka. Você aprenderá a parar de apagar incêndios e começar a projetar sistemas confiáveis.

\n\n

Por que usar filas? Três razões que vão te surpreender

\n\n
    \n
  1. Assincronia — o usuário não espera. A velocidade de resposta do servidor cai de 30 segundos para 5 milissegundos.
  2. \n
  3. Balanceamento de carga — picos de requisições não derrubam o servidor. As tarefas são armazenadas na fila e processadas à medida que os recursos são liberados.
  4. \n
  5. Tolerância a falhas — se um worker falhar, a tarefa permanece na fila. Outro worker a pegará. Os dados não são perdidos.
  6. \n
\n\n

Em Java, existem ferramentas embutidas (ExecutorService, BlockingQueue) e brokers externos (RabbitMQ, Kafka). A escolha depende da escala. Vamos começar pelo básico.

\n\n

Fila simples em Java: ExecutorService e BlockingQueue

\n\n

Se você não precisa de um sistema distribuído, mas apenas deseja mover trabalho pesado para segundo plano — use ThreadPoolExecutor. Este é um pool de threads embutido que retira tarefas de uma fila.

\n\n

Exemplo: pool de threads para processamento de pedidos

\n\n
import java.util.concurrent.*;\n\npublic class OrderProcessor {\n    private final ExecutorService executor;\n\n    public OrderProcessor(int threadCount) {\n        // Cria um pool com número fixo de threads\n        this.executor = Executors.newFixedThreadPool(threadCount);\n    }\n\n    public void processOrder(Order order) {\n        executor.submit(() -> {\n            // Trabalho pesado: geração de recibo, envio de e-mail, atualização de estoque\n            System.out.println("Processando pedido: " + order.getId());\n            try {\n                Thread.sleep(2000); // simulação de trabalho\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println("Pedido " + order.getId() + " processado");\n        });\n    }\n\n    public void shutdown() {\n        executor.shutdown();\n    }\n\n    public static void main(String[] args) {\n        OrderProcessor processor = new OrderProcessor(4);\n        for (int i = 0; i < 10; i++) {\n            processor.processOrder(new Order(i));\n        }\n        processor.shutdown();\n    }\n}\n\nclass Order {\n    private final int id;\n    public Order(int id) { this.id = id; }\n    public int getId() { return id; }\n}
\n\n

O que está acontecendo aqui? Criamos um pool com 4 threads. 10 pedidos serão processados 4 por vez em paralelo. A fila de tarefas em Java é gerenciada internamente pelo ThreadPoolExecutor — por padrão, é uma LinkedBlockingQueue. Quando todas as threads estão ocupadas, as tarefas aguardam na fila.

\n\n

Configuração avançada: prioridades e tolerância a falhas

\n\n

E se as tarefas forem urgentes? Use PriorityBlockingQueue:

\n\n
BlockingQueue<Runnable> priorityQueue = new PriorityBlockingQueue<>(\n    10,\n    Comparator.comparingInt(task -> ((PriorityTask) task).getPriority())\n);\n\nThreadPoolExecutor executor = new ThreadPoolExecutor(\n    2, 4, 60, TimeUnit.SECONDS, priorityQueue\n);
\n\n

Agora, tarefas com alta prioridade

Blogs

Book Recommendations