0Pricing
Java Academy · Aula

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

  1. Criação e Conclusão de CompletableFutures
  2. Encadeamento com thenApply e thenCompose
  3. Combinação de Futures: allOf e anyOf
  4. Tratamento de Erros e Pipeline HTTP Assíncrono
← Voltar para Java Academy