Diferencia entre CompletableFuture, Future y RxJava’s Observable

8 minutos de lectura

avatar de usuario
cuchillo455

me gustaria saber la diferencia entre
CompletableFuture,Future y Observable RxJava.

Lo que sé es que todos son asíncronos, pero

Future.get() bloquea el hilo

CompletableFuture da los métodos de devolución de llamada

RxJava Observable — Similar a CompletableFuture con otros beneficios (no estoy seguro)

Por ejemplo: si el cliente necesita realizar múltiples llamadas de servicio y cuando usamos Futures (Java) Future.get() se ejecutará secuencialmente … me gustaría saber cómo es mejor en RxJava …

y la documentacion http://reactivex.io/intro.html dice

Es difícil usar Futures para componer de manera óptima flujos de ejecución asincrónicos condicionales (o imposible, ya que las latencias de cada solicitud varían en tiempo de ejecución). Esto se puede hacer, por supuesto, pero rápidamente se vuelve complicado (y por lo tanto propenso a errores) o se bloquea prematuramente en Future.get(), lo que elimina el beneficio de la ejecución asincrónica.

Realmente interesado en saber cómo RxJava resuelve este problema. Me resultó difícil de entender a partir de la documentación.

  • ¿Has leído la documentación de cada uno? No estoy totalmente familiarizado con RxJava, pero la documentación parece extremadamente completa de un vistazo. No parece particularmente comparable a los dos futuros.

    – F. Thompson

    11 de febrero de 2016 a las 2:42


  • He pasado pero no puedo entender qué tan diferente es de los futuros de Java… corrígeme si me equivoco

    – shiv455

    11 de febrero de 2016 a las 3:00

  • ¿En qué se parecen los observables a los futuros?

    – F. Thompson

    11 de febrero de 2016 a las 3:08

  • Me gustaría saber dónde es diferente, ¿es diferente en la gestión de subprocesos? EX:Future.get() bloquea el hilo… ¿cómo se manejará en Observable?

    – shiv455

    11 de febrero de 2016 a las 3:13

  • al menos es un poco confuso para mí… ¡una diferencia de alto nivel sería realmente útil!

    – shiv455

    11 de febrero de 2016 a las 3:21

avatar de usuario
Malta

Futuros

Futuros se introdujeron en Java 5 (2004). Son básicamente marcadores de posición para un resultado de una operación que aún no ha terminado. Una vez terminada la operación, el Future contendrá ese resultado. Por ejemplo, una operación puede ser una Ejecutable o Llamable instancia que se envía a un EjecutorService. El remitente de la operación puede utilizar el Future objeto para comprobar si la operación está hecho()o esperar a que termine de usar el bloqueo obtener() método.

Ejemplo:

/**
* A task that sleeps for a second, then returns 1
**/
public static class MyCallable implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        Thread.sleep(1000);
        return 1;
    }

}

public static void main(String[] args) throws Exception{
    ExecutorService exec = Executors.newSingleThreadExecutor();
    Future<Integer> f = exec.submit(new MyCallable());

    System.out.println(f.isDone()); //False

    System.out.println(f.get()); //Waits until the task is done, then prints 1
}

CompletableFuturos

CompletableFuturos se introdujeron en Java 8 (2014). De hecho, son una evolución de los futuros regulares, inspirados en los de Google. Futuros escuchablesparte de Guayaba biblioteca. Son futuros que también te permiten encadenar tareas en una cadena. Puede usarlos para decirle a algún subproceso de trabajo que “vaya a hacer una tarea X, y cuando haya terminado, vaya a hacer esta otra cosa usando el resultado de X”. Con CompletableFutures, puede hacer algo con el resultado de la operación sin bloquear un hilo para esperar el resultado. Aquí hay un ejemplo simple:

/**
* A supplier that sleeps for a second, and then returns one
**/
public static class MySupplier implements Supplier<Integer> {

    @Override
    public Integer get() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            //Do nothing
        }
        return 1;
    }
}

/**
* A (pure) function that adds one to a given Integer
**/
public static class PlusOne implements Function<Integer, Integer> {

    @Override
    public Integer apply(Integer x) {
        return x + 1;
    }
}

public static void main(String[] args) throws Exception {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    CompletableFuture<Integer> f = CompletableFuture.supplyAsync(new MySupplier(), exec);
    System.out.println(f.isDone()); // False
    CompletableFuture<Integer> f2 = f.thenApply(new PlusOne());
    System.out.println(f2.get()); // Waits until the "calculation" is done, then prints 2
}

RxJava

RxJava es toda la biblioteca para programación reactiva creado en Netflix. De un vistazo, parecerá ser similar a Flujos de Java 8. Lo es, excepto que es mucho más poderoso.

De manera similar a Futures, RxJava se puede usar para encadenar un montón de acciones sincrónicas o asincrónicas para crear una canalización de procesamiento. A diferencia de Futures, que son de un solo uso, RxJava funciona en arroyos de cero o más elementos. Incluye flujos interminables con un número infinito de elementos. También es mucho más flexible y potente gracias a un increíblemente rico conjunto de operadores.

A diferencia de los flujos de Java 8, RxJava también tiene un contrapresión mecanismo, que le permite manejar casos en los que diferentes partes de su canal de procesamiento operan en diferentes subprocesos, a diferentes tasas.

La desventaja de RxJava es que, a pesar de la sólida documentación, es una biblioteca desafiante para aprender debido al cambio de paradigma involucrado. El código Rx también puede ser una pesadilla para depurar, especialmente si hay varios subprocesos involucrados y, lo que es peor, si se necesita contrapresión.

Si quieres entrar en él, hay un todo página de varios tutoriales en el sitio web oficial, además del oficial documentación y Javadoc. También puede echar un vistazo a algunos de los videos como Éste que brinda una breve introducción a Rx y también habla sobre las diferencias entre Rx y Futures.

Bonificación: flujos reactivos de Java 9

Flujos reactivos de Java 9 alias API de flujo son un conjunto de Interfaces implementadas por varios flujos reactivos bibliotecas como Rx Java 2, Akka corrientesy Vértice. Permiten que estas bibliotecas reactivas se interconecten, al tiempo que conservan la importante contrapresión.

  • Sería bueno dar un código de ejemplo de cómo Rx hace esto

    – RomanKousta

    23/11/2016 a las 21:01

  • @IgorGanapolsky Sí.

    – Malta

    5 oct 2017 a las 16:45

  • En CompletableFutures usamos métodos de devolución de llamada, estos métodos de devolución de llamada también se bloquearán si la salida de un método es la entrada de otra devolución de llamada. Como bloque futuro con llamada Future.get(). Por qué se dice que Future.get() está bloqueando la llamada mientras que CompletableFutures no bloquea. Por favor explique

    – Deepak

    13 de junio de 2018 a las 4:34

  • @Federico Claro. Cada Future es un marcador de posición para un único resultado que puede o no haberse completado todavía. Si vuelve a realizar la misma operación, obtendrá una nueva Future instancia. RxJava se ocupa de arroyos de resultados que pueden llegar en cualquier momento. Por lo tanto, una serie de operaciones puede devolver un solo observable RxJava que generará una gran cantidad de resultados. Es un poco como la diferencia entre un solo sobre postal y un tubo neumático que sigue bombeando correo.

    – Malta

    22 de septiembre de 2019 a las 11:25


  • @srk sí. Eso bloques hasta que se complete el cálculo.

    – Malta

    8 de diciembre de 2021 a las 15:09

avatar de usuario
Kristoffer

He estado trabajando con Rx Java desde 0.9, ahora en 1.3.2 y pronto migraré a 2.x. Lo uso en un proyecto privado en el que ya trabajo durante 8 años.

Ya no programaría sin esta biblioteca. Al principio era escéptico, pero es un estado mental completamente diferente que necesitas crear. Quiete difícil al principio. A veces miraba las canicas durante horas… jajaja

Es solo una cuestión de práctica y realmente conocer el flujo (también conocido como contrato de observables y observador), una vez que llegue allí, odiará hacerlo de otra manera.

Para mí, no hay realmente un inconveniente en esa biblioteca.

Caso de uso: tengo una vista de monitor que contiene 9 indicadores (cpu, memoria, red, etc.). Al iniciar la vista, la vista se suscribe a una clase de monitor del sistema que devuelve un observable (intervalo) que contiene todos los datos de los 9 metros. Empujará cada segundo un nuevo resultado a la vista (¡¡así que no sondeando !!!). Ese observable usa un mapa plano para obtener datos simultáneamente (¡asincrónicos!) De 9 fuentes diferentes y comprime el resultado en un nuevo modelo que su vista obtendrá en onNext().

¿Cómo diablos vas a hacer eso con futuros, completables, etc… Buena suerte! 🙂

Rx Java resuelve muchos problemas en la programación para mí y hace que sea mucho más fácil…

ventajas:

  • ¡¡¡Apátrida!!! (Algo importante para mencionar, quizás lo más importante)
  • Gestión de subprocesos lista para usar
  • Cree secuencias que tengan su propio ciclo de vida
  • Todo son observables por lo que el encadenamiento es fácil.
  • Menos código para escribir
  • Frasco único en classpath (muy liviano)
  • Altamente concurrente
  • Ya no hay infierno de devolución de llamada
  • Basado en suscriptores (contrato estrecho entre el consumidor y el productor)
  • Estrategias de contrapresión (disyuntores similares)
  • Espléndido manejo y recuperación de errores
  • Muy buena documentación (canicas <3)
  • Control completo
  • Mucho mas …

Desventajas: – Difícil de probar

  • ~”Ya no programaría sin esta biblioteca.” Entonces, ¿RxJava es el final de todo para todos los proyectos de software?

    – Igor Ganapolski

    5 oct 2017 a las 16:38

  • ¿Es útil incluso si no tengo Stream of Asynchronous events?

    – Mukesh Verma

    30 de octubre de 2019 a las 9:07

de Java Future es un marcador de posición para contener algo que se completará en el futuro con una API de bloqueo. Tendrás que usar su’ isDone() método para sondearlo periódicamente para verificar si esa tarea ha terminado. Ciertamente, puede implementar su propio código asincrónico para administrar la lógica de sondeo. Sin embargo, incurre en más código repetitivo y sobrecarga de depuración.

de Java CompletableFuture es innovado por Scala’s Future. Lleva un método interno de devolución de llamada. Una vez que haya terminado, el método de devolución de llamada se activará y le indicará al subproceso que se debe ejecutar la operación descendente. por eso tiene thenApply método para realizar más operaciones en el objeto envuelto en el CompletableFuture.

de RxJava Observable es una versión mejorada de CompletableFuture. Le permite manejar la contrapresión. En el thenApply método (e incluso con sus hermanos thenApplyAsync) que mencionamos anteriormente, esta situación podría ocurrir: el método descendente quiere llamar a un servicio externo que a veces puede no estar disponible. En este caso, el CompleteableFuture fallará por completo y tendrá que manejar el error usted mismo. Sin embargo, Observable le permite manejar la contrapresión y continuar la ejecución una vez que el servicio externo esté disponible.

Además, hay una interfaz similar de Observable: Flowable. Están diseñados para diferentes propósitos. Normalmente Flowable se dedica a manejar las operaciones en frío y no cronometradas, mientras Observable se dedica a manejar las ejecuciones que requieren respuestas instantáneas. Vea los documentos oficiales aquí: https://github.com/ReactiveX/RxJava#backpression

La principal ventaja de CompletableFuture sobre Future normal es que CompletableFuture aprovecha la API de transmisión extremadamente poderosa y le brinda controladores de devolución de llamada para encadenar sus tareas, lo cual está absolutamente ausente si usa Future normal. Que además de proporcionar una arquitectura asincrónica, CompletableFuture es el camino a seguir para manejar tareas de reducción de mapas pesadas de cómputo, sin preocuparse demasiado por el rendimiento de la aplicación.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad