Programação Assíncrona em Java: guia completo na prática

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

Introdução à programação assíncrona em Java



Aplicações modernas exigem alta performance e capacidade de resposta. Os usuários não estão dispostos a esperar enquanto a aplicação processa uma consulta ao banco de dados ou realiza uma chamada de rede. É aqui que a programação assíncrona em Java entra em cena — uma abordagem que permite não bloquear o fluxo principal de execução enquanto aguarda a conclusão de operações demoradas.



Ao contrário do multithreading tradicional, onde você gerencia explicitamente as threads, a programação assíncrona oferece abstrações de nível mais alto. Em vez de criar novas threads manualmente, você utiliza CompletableFuture, ExecutorService e outras ferramentas fornecidas pela Java Concurrency API.



Neste artigo, abordaremos os conceitos-chave da programação assíncrona em Java com exemplos práticos. Você aprenderá como processar tarefas assíncronas, encadeá-las e trabalhar eficientemente com multithreading.



Ferramentas principais da programação assíncrona em Java



1. CompletableFuture — a base da assincronicidade



CompletableFuture é uma classe introduzida no Java 8 que fornece uma API poderosa para programação assíncrona. Ela permite criar tarefas assíncronas, combiná-las, tratar erros e transformar resultados.



Vejamos um exemplo simples de criação e execução de uma tarefa assíncrona:



import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;

public class AsyncExample { public static void main(String[] args) throws ExecutionException, InterruptedException { // Criando uma tarefa assíncrona CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); // Simulando uma operação demorada } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return "Resultado da operação assíncrona"; });

// Adicionando um manipulador de conclusão future.thenAccept(result -> System.out.println("Resultado obtido: " + result));

// O fluxo principal continua trabalhando System.out.println("O fluxo principal continua a execução");

// Aguardando a conclusão (apenas para demonstração) future.get(); }}


Observe que supplyAsync() por padrão utiliza ForkJoinPool.commonPool(). Este é um pool de threads otimizado para tarefas paralelas.



2. ExecutorService — gerenciamento do pool de threads



Para um controle mais refinado sobre a execução de tarefas assíncronas, utilize ExecutorService. Isso permite definir o número de threads, seu comportamento e a estratégia de processamento de tarefas.



import java.util.concurrent.*;

public class ExecutorServiceExample { public static void main(String[] args) { // Criando um pool de 4 threads ExecutorService executor = Executors.newFixedThreadPool(4);

// Criando um CompletableFuture com um executor personalizado CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return 42; }, executor);

// Processando o resultado future.thenAccept(result -> { System.out.println("Resultado: " + result); executor.shutdown(); // Importante! Fechar o pool });

System.out.println("O fluxo principal não é bloqueado"); }}


Importante: Sempre feche o ExecutorService com shutdown() ou shutdownNow() para evitar vazamento de recursos.



3. Combinação

Blogs

Book Recommendations