0Pricing
Java Academy · Lección

Combinación de futures: allOf y anyOf

Espere a todos los futures con allOf y compítalos con anyOf para implementar lógica de tiempos de espera y fallback.

Combinación de futures: allOf y anyOf es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.

¿Por qué combinar futures?

Cuando varias tareas asíncronas independientes pueden ejecutarse en paralelo, querrá esperar a que todas, o la primera, terminen antes de continuar. allOf y anyOf gestionan ambos casos.

allOf: esperar a todos los futures

CompletableFuture.allOf(futures...) devuelve un CompletableFuture<Void> que se completa cuando terminan TODOS los futures de entrada. Si alguno falla, allOf también falla.

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();

Recopilar los resultados de allOf

Como allOf devuelve Void, recopile los resultados llamando a join() en cada future individual después 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: gana el primero en completarse

CompletableFuture.anyOf(futures...) devuelve un CompletableFuture<Object> que se completa con el resultado del primer future que termine, independientemente de su tipo.

CompletableFuture<Object> first = CompletableFuture.anyOf(
    fetchFromCacheAsync(),
    fetchFromDbAsync(),
    fetchFromApiAsync()
);
System.out.println("Fastest result: " + first.join());

anyOf como alternativa para tiempos de espera

Haga competir un cálculo real con un future de tiempo de espera. Gane el que se complete primero para implementar un patrón de tiempo de espera sin bloqueos.

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 o posterior)

orTimeout(time, unit) completa el future con TimeoutException si no termina a tiempo. Es más limpio que el patrón manual de anyOf con tiempo de espera.

CompletableFuture<String> result = fetchDataAsync()
    .orTimeout(3, TimeUnit.SECONDS)
    .exceptionally(ex -> "timeout-default");
System.out.println(result.join());

Llamadas HTTP paralelas con allOf

Envíe solicitudes a varios servicios en paralelo y, después, combine los resultados. Es mucho más rápido que realizar llamadas secuenciales cuando los servicios son independientes.

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();

Gestión de errores en allOf

Si falla un future de allOf, el future devuelto falla inmediatamente. Envuelva los futures individuales con exceptionally para evitar que un solo error haga fallar todo el lote.

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 con tipos diferentes

allOf acepta futures de tipos diferentes. Después de combinarlos, convierta el resultado de cada future al tipo esperado.

CompletableFuture<User> userFuture   = fetchUser(id);
CompletableFuture<Config> configFuture = fetchConfig();
CompletableFuture.allOf(userFuture, configFuture).join();
User   user   = userFuture.join();
Config config = configFuture.join();

Combinar allOf y thenApply

Encadene thenApply a allOf para agregar los resultados en cuanto se completen todos los futures.

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());

Consideraciones sobre el pool de hilos

Todos los futures de una llamada a allOf o anyOf pueden ejecutarse simultáneamente. Asegúrese de que el pool de hilos tenga suficientes hilos o use hilos virtuales (Java 21 o posterior) para evitar la inanición.

// With virtual threads (Java 21+):
ExecutorService vt = Executors.newVirtualThreadPerTaskExecutor();
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> httpGet(url), vt);

Propagación de la cancelación

allOf y anyOf no cancelan automáticamente los futures restantes cuando uno se completa o se cancela. Cancele cada uno individualmente si es necesario.

CompletableFuture<Object> first = CompletableFuture.anyOf(f1, f2, f3);
first.thenRun(() -> Stream.of(f1, f2, f3).forEach(f -> f.cancel(true)));

Comprobación rápida

¿Qué devuelve CompletableFuture.anyOf?

Resumen

allOf espera a todos los futures (fan-in). anyOf toma el primer resultado (competición). Use orTimeout para los tiempos de espera. Envuelva los futures individuales con exceptionally para evitar que un solo error haga fallar el lote.

Preguntas frecuentes

¿La lección «Combinación de futures: allOf y anyOf» es gratis?

Sí — el texto completo de «Combinación de futures: allOf y anyOf» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Combinación de futures: allOf y anyOf»?

Espere a todos los futures con allOf y compítalos con anyOf para implementar lógica de tiempos de espera y fallback. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Java Academy?

No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Combinación de futures: allOf y anyOf»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Java Academy?

Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Creación y finalización de CompletableFutures
  2. Encadenamiento con thenApply y thenCompose
  3. Combinación de futures: allOf y anyOf
  4. Gestión de errores y canalización HTTP asíncrona
← Volver a Java Academy