¿Cuál es la diferencia entre Future
y Promise
?
Ambos actúan como un marcador de posición para resultados futuros, pero ¿dónde está la principal diferencia?
java
concurrency
future
promise
usuario1170330
fuente
fuente
Promise
y depende de usted mantenerlo. Cuando alguien más te hace una promesa, debes esperar para ver si la cumplen en elFuture
Respuestas:
Según esta discusión ,
Promise
finalmente se ha pedidoCompletableFuture
su inclusión en Java 8, y su javadoc explica:También se da un ejemplo en la lista:
Tenga en cuenta que la API final es ligeramente diferente pero permite una ejecución asincrónica similar:
fuente
(No estoy completamente contento con las respuestas hasta ahora, así que aquí está mi intento ...)
Creo que el comentario de Kevin Wright ( "Puedes hacer una promesa y depende de ti cumplirla. Cuando alguien más te hace una promesa, debes esperar para ver si la cumplen en el futuro" ) lo resume bastante bien, pero algunos La explicación puede ser útil.
Los futuros y las promesas son conceptos bastante similares, la diferencia es que un futuro es un contenedor de solo lectura para un resultado que aún no existe, mientras que una promesa se puede escribir (normalmente solo una vez). El Java 8 CompletableFuture y el Guava SettableFuture pueden considerarse promesas, porque su valor se puede establecer ("completar"), pero también implementan la interfaz Future, por lo tanto, no hay diferencia para el cliente.
El resultado del futuro será establecido por "alguien más", por el resultado de un cálculo asincrónico. Observe cómo FutureTask , un futuro clásico, debe inicializarse con un Callable o Runnable, no hay un constructor sin argumentos, y Future y FutureTask son de solo lectura desde el exterior (los métodos establecidos de FutureTask están protegidos). El valor se establecerá en el resultado del cálculo desde el interior.
Por otro lado, el resultado de una promesa puede ser establecido por "usted" (o de hecho por cualquiera) en cualquier momento porque tiene un método de establecimiento público. Tanto CompletableFuture como SettableFuture se pueden crear sin ninguna tarea, y su valor se puede establecer en cualquier momento. Envía una promesa al código del cliente y la cumple más tarde como lo desee.
Tenga en cuenta que CompletableFuture no es una promesa "pura", puede inicializarse con una tarea como FutureTask, y su característica más útil es el encadenamiento no relacionado de los pasos de procesamiento.
También tenga en cuenta que una promesa no tiene que ser un subtipo de futuro y no tiene que ser el mismo objeto. En Scala, un objeto Futuro se crea mediante un cálculo asincrónico o mediante un objeto Promise diferente . En C ++, la situación es similar: el objeto de promesa es utilizado por el productor y el futuro por el consumidor. La ventaja de esta separación es que el cliente no puede establecer el valor del futuro.
Tanto Spring como EJB 3.1 tienen una clase AsyncResult, que es similar a las promesas de Scala / C ++. AsyncResult implementa Future pero este no es el futuro real: los métodos asincrónicos en Spring / EJB devuelven un objeto Future diferente de solo lectura a través de cierta magia de fondo, y el cliente puede usar este segundo futuro "real" para acceder al resultado.
fuente
Soy consciente de que ya hay una respuesta aceptada pero, sin embargo, me gustaría agregar mis dos centavos:
TLDR: Future y Promise son los dos lados de una operación asincrónica: consumidor / llamante versus productor / implementador .
Como llamador de un método API asíncrono, obtendrá
Future
un control del resultado del cálculo. Puede, por ejemplo, invocarloget()
para esperar a que se complete el cálculo y recuperar el resultado.Ahora piense en cómo se implementa este método API: el implementador debe devolver un
Future
inmediato. Son responsables de completar ese futuro tan pronto como se realice el cálculo (que sabrán porque está implementando la lógica de despacho ;-)). Utilizarán unPromise
/CompletableFuture
para hacer exactamente eso: construir y devolver elCompletableFuture
inmediatamente, y llamarcomplete(T result)
una vez que se haya realizado el cálculo.fuente
Daré un ejemplo de lo que es Promise y cómo se puede establecer su valor en cualquier momento, en oposición a Future, cuyo valor solo es legible.
Supongamos que tienes una madre y le pides dinero.
La salida de eso es:
La promesa de mamá fue creada, pero esperó algún evento de "finalización".
Creaste tal evento, aceptando su promesa y anunciando tus planes para agradecer a tu madre:
En este momento, mamá comenzó a abrir su bolso ... pero muy lento ...
y el padre interfirió mucho más rápido y completó la promesa en lugar de su madre:
¿Has notado un albacea que escribí explícitamente?
Curiosamente, si utiliza un ejecutor implícito predeterminado (commonPool) y el padre no está en casa, pero solo la madre con su "bolso lento", entonces su promesa solo se completará, si el programa dura más de lo que la madre necesita para obtener dinero del bolso.
El ejecutor predeterminado actúa como un "demonio" y no espera a que se cumplan todas las promesas. No he encontrado una buena descripción de este hecho ...
fuente
No estoy seguro de si esto puede ser una respuesta, pero como veo lo que otros han dicho sobre alguien, puede parecer que necesita dos abstracciones separadas para ambos conceptos, de modo que uno de ellos (
Future
) es solo una vista de solo lectura del otro (Promise
) ... pero en realidad esto no es necesario.Por ejemplo, eche un vistazo a cómo se definen las promesas en javascript:
https://promisesaplus.com/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
El enfoque está en la capacidad de compilación utilizando el
then
método como:lo que hace que el cálculo asíncrono parezca síncrono:
lo cual es genial (No es tan genial como async-await pero async-await simplemente elimina la repetitiva .... luego (función (resultado) {.... de ella).
Y en realidad su abstracción es bastante buena como constructor de promesas
le permite proporcionar dos devoluciones de llamada que se pueden utilizar para completar con
Promise
éxito o con un error. De modo que solo el código que construye elPromise
puede completarlo y el código que recibe unPromise
objeto ya construido tiene la vista de solo lectura.Con la herencia, se puede lograr lo anterior si resolver y rechazar son métodos protegidos.
fuente
CompletableFuture
puede tener alguna similitud con unPromise
pero todavía no es unPromise
, porque la forma en que se pretende consumir es diferente:Promise
el resultado de a se consume al llamarthen(function)
, y la función se ejecuta en el contexto del productor inmediatamente después de que el productor llamaresolve
. ElFuture
resultado de A se consume al llamar, loget
que hace que el subproceso del consumidor espere hasta que el subproceso del productor haya generado el valor y luego lo procese en el consumidor.Future
es inherentemente multiproceso, pero ...Promise
solo hilo (y de hecho, ese es el entorno preciso para el que fueron diseñados originalmente: las aplicaciones javascript generalmente solo tienen un solo hilo, por lo que no puede implementarloFuture
allí).Promise
es, por lo tanto, mucho más liviano y eficiente queFuture
, peroFuture
puede ser útil en situaciones que son más complejas y requieren cooperación entre hilos que no se pueden organizar fácilmente usandoPromise
s. Para resumir:Promise
es un modelo push, mientras queFuture
es un modelo pull (cf Iterable vs Observable)XMLHttpRequest
). No creo en la afirmación de eficiencia, ¿tienes algunas cifras? +++ Dicho eso, una muy buena explicación.get
a una resoluciónFuture
no resuelta necesariamente implicará cambios de contexto de 2 hilos, que al menos unos años atrás probablemente requerirían alrededor de 50 de nosotros .Para el código del cliente, Promise es para observar o adjuntar una devolución de llamada cuando hay un resultado disponible, mientras que Future es esperar el resultado y luego continuar. Teóricamente, cualquier cosa que sea posible hacer con futuros, lo que se puede hacer con promesas, pero debido a la diferencia de estilo, la API resultante para promesas en diferentes idiomas facilita el encadenamiento.
fuente
No hay un método establecido en la interfaz Future, solo obtiene un método, por lo que es de solo lectura. Sobre CompletableFuture, este artículo puede ser útil. futuro completo
fuente