Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
O uso do CompletableFuture em Java é uma maneira eficaz de trabalhar com operações assíncronas, permitindo que os desenvolvedores escrevam código mais limpo e legível. A principal vantagem do CompletableFuture é a sua capacidade de facilitar o processamento paralelo e lidar com múltiplas operações assíncronas de forma simples. Com seu uso, é possível executar tarefas em background sem bloquear a thread principal, melhorando a eficiência das aplicações.
Além disso, o CompletableFuture oferece uma API rica que permite combinar várias operações assíncronas e manipular resultados de forma intuitiva. Essa funcionalidade torna-o um recurso poderoso para desenvolvedores que buscam otimizar o desempenho de suas aplicações Java. O artigo a seguir fornecerá uma visão geral detalhada e exemplos práticos sobre como utilizar o CompletableFuture no dia a dia da programação.
O CompletableFuture
é uma ferramenta poderosa em Java para programação assíncrona. Este componente permite que tarefas sejam executadas de forma não bloqueante, facilitando a criação de aplicações mais responsivas.
O CompletableFuture
é uma implementação da interface Future
, que permite que os desenvolvedores executem operações de forma assíncrona. Ele facilita a escrita de código assíncrono em Java, permitindo encadear ações que devem ser realizadas após a conclusão da tarefa inicial. Por exemplo, uma operação de rede pode ser iniciada, e enquanto aguarda a resposta, outras tarefas podem ser processadas.
Além disso, ele oferece métodos como supplyAsync
, thenApply
, e exceptionally
, que tornam a manipulação de resultados e exceções mais simples. O uso deste framework melhora a legibilidade e a manutenção do código.
As vantagens do CompletableFuture
incluem maior facilidade no tratamento de múltiplas tarefas simultaneamente. Ele permite que várias operações sejam realizadas em paralelo, aumentando a eficiência do programa. Com o uso do método allOf
, o desenvolvedor pode esperar por várias CompletableFutures
concluírem antes de prosseguir.
Outro benefício é a facilidade de composição. Tarefas podem ser encadeadas usando métodos como thenCompose
, proporcionando uma estrutura clara e lógica para o fluxo de execução. Isso minimiza o uso de callbacks aninhados, um problema comum em outras abordagens.
Enquanto o Future
proporciona um modo básico de trabalhar com tarefas assíncronas, ele carece de métodos para compor e lidar com a execução de forma mais eficiente. O CompletableFuture
vai além, permitindo não apenas esperar pelo resultado, mas também especificar ações a serem realizadas após a conclusão da tarefa.
Além disso, um Future
é limitado a operações que bloqueiam a thread até que a tarefa seja completada. Por outro lado, o CompletableFuture
é projetado para ser não bloqueante. Isso resulta em uma melhor performance em aplicações que precisam de alta responsividade e gestão eficiente de recursos.
Ao trabalhar com CompletableFuture
, o programador pode realizar operações assíncronas de modo simples e funcional. A seguir, são abordadas maneiras de criar, completar e encadear CompletableFuture
, além de como lidar com exceções.
Existem várias formas de criar um CompletableFuture
, pode-se usar o método estático CompletableFuture.supplyAsync()
, que executa uma tarefa assíncrona. Este método aceita um Supplier
, que representa uma função que pode ser executada de forma assíncrona.
Por exemplo:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// tarefa longa
return "Resultado";
});
JavaOu criar da forma mais básica, que seria criando uma instancia de forma manual.
CompletableFuture<String> future = new CompletableFuture<>();
JavaAlém disso, CompletableFuture.runAsync()
é útil quando não se espera um resultado, mas sim apenas a execução de uma tarefa:
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// executar ação
});
JavaUm CompletableFuture
pode ser completado manualmente usando o método complete()
. Isso é útil em situações onde se deseja forçar a conclusão de uma tarefa:
CompletableFuture<String> future = new CompletableFuture<>();
future.complete("resultado pronto");
JavaO estado do CompletableFuture
muda para completo, permitindo que o resultado seja acessado. Se a execução assíncrona foi concluída, isso não afeta o resultado, que pode ser obtido com get()
.
Encadear operações é uma das principais funcionalidades do CompletableFuture
. O método thenApply()
transforma o resultado de uma operação anterior:
future.thenApply(result -> {
return result.toUpperCase();
});
JavathenAccept()
é semelhante, mas não retorna um valor; ele apenas consome o resultado:
future.thenAccept(result -> {
System.out.println("Resultado: " + result);
});
JavaPor outro lado, thenRun()
não recebe um resultado, executando uma ação após a conclusão da tarefa original:
future.thenRun(() -> {
System.out.println("Tarefa concluída!");
});
JavaExemplo de uso:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Primeiro resultado")
.thenApply(resultado -> resultado + " e mais um passo.")
.thenApply(resultado -> resultado + " Finalizado.");
future.thenAccept(System.out::println); // Imprime o resultado final
JavaPara combinar dois CompletableFuture
, utiliza-se thenCombine()
, que permite operar sobre dois resultados:
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 2);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 3);
future1.thenCombine(future2, (result1, result2) -> result1 + result2)
.thenAccept(System.out::println);
JavathenCompose()
é útil para encadear tarefas que retornam CompletableFuture
, permitindo uma forma mais fluida de criar chamadas em sequência:
future1.thenCompose(result -> CompletableFuture.supplyAsync(() -> result * 2));
JavaMais exemplos:
// Combinando dois futuros com thenCombine
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Resultado 1");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Resultado 2");
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (res1, res2) -> res1 + " e " + res2);
combinedFuture.thenAccept(System.out::println); // Imprime: Resultado 1 e Resultado 2
// Usando allOf para esperar por múltiplos futuros
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
allFutures.thenRun(() -> System.out.println("Todos os futuros foram completados."));
JavaPara gerenciar exceções em operações assíncronas, exceptionally()
fornece uma maneira de lidar com falhas:
future.exceptionally(ex -> {
System.err.println("Erro: " + ex.getMessage());
return "Valor padrão";
});
JavaO método handle()
permite lidar com resultados e exceções, fornecendo um tratamento mais flexível:
future.handle((result, ex) -> {
if (ex != null) {
return "Erro tratado";
}
return result;
});
JavaEssas abordagens asseguram que o fluxo de execução permaneça claro e controlado, mesmo em caso de falhas.
Você pode bloquear a thread principal até que o futuro seja concluído usando os métodos get
ou join
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Resultado assíncrono");
try {
String resultado = future.get(); // Bloqueia até que o resultado esteja disponível
System.out.println(resultado);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
JavaO CompletableFuture
é uma ferramenta poderosa para lidar com operações assíncronas em Java. Ele suporta diversos padrões de programação assíncrona, como encadeamento, tratamento de exceções e combinações de múltiplos futuros, tornando o código mais eficiente e legível.