Combinação de Futures: allOf e anyOf
Aguarde todos os futures com allOf e faça uma disputa entre eles com anyOf para implementar lógica de timeout e fallback.
Combinação de Futures: allOf e anyOf é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 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 combinar futuros?
Quando tarefas assíncronas independentes podem ser executadas em paralelo, você precisa esperar que todas — ou a primeira — sejam concluídas antes de prosseguir. allOf e anyOf lidam com os dois casos.
allOf: esperando todos os futuros
CompletableFuture.allOf(futures...) retorna um CompletableFuture<Void> que é concluído quando ALL os futuros de entrada são concluídos. Se algum falhar, allOf também falhará.
CompletableFuture<String> f1 = fetchUserAsync();
CompletableFuture<List<Order>> f2 = fetchOrdersAsync();
CompletableFuture<Double> f3 = fetchBalanceAsync();
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
all.join(); // wait for all three
String user = f1.join();
List<Order> orders = f2.join();
Double balance = f3.join();Coletando os resultados de allOf
Como allOf retorna Void, colete os resultados chamando join() em cada futuro individual depois de allOf.join().
List<CompletableFuture<String>> futures = List.of(
fetchAsync("url1"), fetchAsync("url2"), fetchAsync("url3"));
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()))
.thenAccept(results -> results.forEach(System.out::println))
.join();anyOf: o primeiro concluído vence
CompletableFuture.anyOf(futures...) retorna um CompletableFuture<Object> que é concluído com o resultado do primeiro futuro concluído, independentemente do tipo.
CompletableFuture<Object> first = CompletableFuture.anyOf(
fetchFromCacheAsync(),
fetchFromDbAsync(),
fetchFromApiAsync()
);
System.out.println("Fastest result: " + first.join());anyOf para tempo limite alternativo
Coloque uma computação real para disputar com um futuro de tempo limite. O que for concluído primeiro vence — implementando um padrão de tempo limite sem bloqueio.
CompletableFuture<String> real = fetchDataAsync();
CompletableFuture<String> timeout = CompletableFuture
.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return "timeout-default";
});
String result = (String) CompletableFuture.anyOf(real, timeout).join();orTimeout (Java 9 ou posterior)
orTimeout(time, unit) conclui o futuro com TimeoutException se ele não terminar a tempo. É mais simples que o padrão manual de tempo limite com anyOf.
CompletableFuture<String> result = fetchDataAsync()
.orTimeout(3, TimeUnit.SECONDS)
.exceptionally(ex -> "timeout-default");
System.out.println(result.join());Chamadas HTTP paralelas com allOf
Envie solicitações para vários serviços em paralelo e depois reúna os resultados. Isso é muito mais rápido que chamadas sequenciais quando os serviços são independentes.
List<String> urls = List.of(url1, url2, url3);
List<CompletableFuture<String>> futures = urls.stream()
.map(url -> CompletableFuture.supplyAsync(() -> httpGet(url)))
.collect(Collectors.toList());
List<String> responses = CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList()))
.join();Tratamento de erros em allOf
Se um futuro em allOf falhar, o futuro retornado falhará imediatamente. Envolva os futuros individuais com exceptionally para evitar que uma falha faça todo o lote falhar.
List<CompletableFuture<String>> safe = futures.stream()
.map(f -> f.exceptionally(ex -> "ERROR: " + ex.getMessage()))
.collect(Collectors.toList());
CompletableFuture.allOf(safe.toArray(new CompletableFuture[0])).join();allOf com tipos diferentes
allOf aceita futuros de tipos diferentes. Depois de reuni-los, converta o resultado de cada futuro para o tipo esperado.
CompletableFuture<User> userFuture = fetchUser(id);
CompletableFuture<Config> configFuture = fetchConfig();
CompletableFuture.allOf(userFuture, configFuture).join();
User user = userFuture.join();
Config config = configFuture.join();Compondo allOf e thenApply
Encadeie thenApply em allOf para agregar os resultados assim que todos os futuros forem concluídos.
CompletableFuture<String> summary =
CompletableFuture.allOf(f1, f2, f3)
.thenApply(v -> "User: " + f1.join() +
", Orders: " + f2.join().size() +
", Balance: " + f3.join());
System.out.println(summary.join());Considerações sobre o pool de threads
Todos os futuros em uma chamada de allOf / anyOf podem ser executados simultaneamente. Garanta que o pool de threads tenha threads suficientes ou utilize threads virtuais (Java 21 ou posterior) para evitar a falta de threads disponíveis.
// With virtual threads (Java 21+):
ExecutorService vt = Executors.newVirtualThreadPerTaskExecutor();
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> httpGet(url), vt);Propagação do cancelamento
allOf / anyOf não cancelam automaticamente os futuros restantes quando um deles é concluído ou cancelado. Cancele cada um individualmente, se necessário.
CompletableFuture<Object> first = CompletableFuture.anyOf(f1, f2, f3);
first.thenRun(() -> Stream.of(f1, f2, f3).forEach(f -> f.cancel(true)));Verificação rápida
O que CompletableFuture.anyOf retorna?
Recapitulação
allOf espera por todos os futuros (agregação). anyOf usa o primeiro resultado (disputa). Utilize orTimeout para tempos limite. Envolva os futuros individuais com exceptionally para evitar que uma falha faça o lote falhar.
Perguntas Frequentes
A aula “Combinação de Futures: allOf e anyOf” é grátis?
Sim — o texto completo de “Combinação de Futures: allOf e anyOf” é 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 “Combinação de Futures: allOf e anyOf”?
Aguarde todos os futures com allOf e faça uma disputa entre eles com anyOf para implementar lógica de timeout e fallback. 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 3 de 4.
Quanto tempo leva a aula “Combinação de Futures: allOf e anyOf”?
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
- Criação e Conclusão de CompletableFutures
- Encadeamento com thenApply e thenCompose
- Combinação de Futures: allOf e anyOf
- Tratamento de Erros e Pipeline HTTP Assíncrono