springutilities springlayout listmodel layouts item ejemplo java concurrency future promise

java - springlayout - Diferencia entre el futuro y la promesa



springlayout ejemplo (7)

(No estoy del todo 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 mantenerla. Cuando alguien más te hace una promesa debes esperar para ver si la honran 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 Futuro, por lo tanto, no hay diferencia para el cliente.

El resultado del futuro será establecido por "otra persona", 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 tanto Future como 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 cualquier persona) 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 puede establecerse en cualquier momento. Envía una promesa al código del cliente y lo completa más tarde como lo desee.

Tenga en cuenta que CompletableFuture no es una promesa "pura", se puede inicializar 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 Future 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 objeto 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 magia de fondo, y este segundo futuro "real" puede ser utilizado por el cliente para acceder al resultado.

¿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 diferencia principal?


Daré un ejemplo de lo que es Promesa y cómo se puede establecer su valor en cualquier momento, en oposición a Futuro, cuyo valor solo es legible.

Supongamos que tienes una madre y le pides dinero.

Ahora, engañas a tu madre para que te haga una promesa de una eventual donación, ella te da ese objeto de promesa, pero ella todavía no está realmente dispuesta a cumplirlo:

Supplier<Integer> momsPurse = ()-> { try { Thread.sleep(1000);//mom is busy } catch (InterruptedException e) { ; } return 100; }; ExecutorService ex = Executors.newFixedThreadPool(10); CompletableFuture<Integer> promise = CompletableFuture.supplyAsync(momsPurse, ex);

Eres feliz, corres para agradecerle a tu madre:

promise.thenAccept(u->System.out.println("Thank you mom for $" + u ));

Pero tu padre interfiere y generalmente aborta los planes de la madre y cumple la promesa (¡establece su valor!) Con una contribución mucho menor, como hacen los padres, muy resueltamente, mientras mamá abre lentamente su bolso (fíjate Thread.sleep (...)):

promise.complete(10);

La salida de eso es:

Thank you mom for $10

La promesa de mamá fue creada, pero esperó algún evento de "finalización".

CompletableFuture<Integer> promise...

Usted creó tal evento, aceptando su promesa y anunciando sus planes para agradecer a su madre:

promise.thenAccept...

En este momento mamá comenzó a abrir su bolso ... pero muy lento ...

y el padre intervino mucho más rápido y completó la promesa en lugar de su madre:

promise.complete(10);

¿Has notado a un ejecutor que escribí explícitamente? Es interesante que si usa el ejecutor implícito predeterminado (commonPool) y el padre no está en casa, solo la madre con su "bolso lento", entonces su promesa solo se completará, si el programa vive más tiempo del que mamá necesita para obtener dinero de la bolsa. Quiero decir que el ejecutor predeterminado actúa de una manera de "daemon". No he encontrado una buena descripción de este hecho ...


No estoy seguro si esto puede ser una respuesta, pero cuando veo lo que otros han dicho para 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, mira 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 foco está en la capacidad de compilación usando el método then como:

asyncOp1() .then(function(op1Result){ // do something return asyncOp2(); }) .then(function(op2Result){ // do something more return asyncOp3(); }) .then(function(op3Result){ // do something even more return syncOp4(op3Result); }) ... .then(function(result){ console.log(result); }) .catch(function(error){ console.log(error); })

que hace que el cálculo asincrónico se vea como sincrónico:

try { op1Result = syncOp1(); // do something op1Result = syncOp2(); // do something more op3Result = syncOp3(); // do something even more syncOp4(op3Result); ... console.log(result); } catch(error) { console.log(error); }

lo cual es genial (No tan genial como async-await pero async-await simplemente elimina la repetición ... luego (función (resultado) {.... de ella).

Y en realidad su abstracción es bastante buena como el constructor de la promesa

new Promise( function(resolve, reject) { /* do it */ } );

le permite proporcionar dos devoluciones de llamada que pueden usarse para completar la Promise exitosamente o con un error. Para que solo el código que construye la Promise pueda completarlo y el código que recibe un objeto Promise ya construido tenga la vista de solo lectura.

Con la herencia, lo anterior se puede lograr si la resolución y el rechazo son métodos protegidos.


No hay un método establecido en la interfaz Futuro, solo obtiene el método, por lo que es de solo lectura. Acerca de CompletableFuture, este artículo puede ser útil. completablefuture


Para el código de cliente, Promise es para observar o adjuntar una devolución de llamada cuando hay un resultado disponible, mientras que Future espera el resultado y luego continúa. Teóricamente, cualquier cosa que se pueda 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.


Según esta discusión , Promise finalmente se ha llamado CompletableFuture para su inclusión en Java 8, y su javadoc explica:

Un Futuro que puede completarse explícitamente (establecer su valor y estado), y puede usarse como un CompletionStage, que admite funciones dependientes y acciones que se desencadenan al completarse.

Un ejemplo también se da en la lista:

f.then((s -> aStringFunction(s)).thenAsync(s -> ...);

Tenga en cuenta que la API final es ligeramente diferente, pero permite una ejecución asincrónica similar:

CompletableFuture<String> f = ...; f.thenApply(this::modifyString).thenAccept(System.out::println);


Soy consciente de que ya hay una respuesta aceptada pero me gustaría agregar mis dos centavos:

Como llamador de un método API asíncrono, obtendrá un Future como manejador del resultado del cálculo. Puede, por ejemplo, llamar a get() para esperar a que se complete el cálculo y recuperar el resultado.

Ahora piense en cómo se implementa realmente este método API: el implementador debe devolver un Future inmediatamente. Ella es responsable de completar ese futuro tan pronto como se realice el cálculo (que ella sabrá porque está implementando la lógica de despacho ;-)). Ella usará un Promise / CompletableFuture para hacer justamente eso: Construya y devuelva el CompletableFuture inmediato, y llame al complete(T result) una vez que el cálculo haya finalizado.

TLDR: futuro y promesa son los dos lados de una operación asincrónica: consumidor / llamante vs. productor / implementador .