What's the difference between a Future and a P

2019-01-15 23:33发布

What's the difference between Future and Promise?
They both act like a placeholder for future results, but where is the main difference?

7条回答
The star\"
2楼-- · 2019-01-16 00:15

I am aware that there's already an accepted answer but would like to add my two cents nevertheless:

TLDR: Future and Promise are the two sides of an asynchronous operation: consumer/caller vs. producer/implementor.

As a caller of an asynchronous API method, you will get a Future as a handle to the computation's result. You can e.g. call get() on it to wait for the computation to complete and retrieve the result.

Now think of how this API method is actually implemented: The implementor must return a Future immediately. She is responsible for completing that future as soon as the computation is done (which she will know because she is implementing the dispatch logic ;-)). She will use a Promise/CompletableFuture to do just that: Construct and return the CompletableFuture immediately, and call complete(T result) once the computation is done.

查看更多
仙女界的扛把子
3楼-- · 2019-01-16 00:15

I will give an example of what is Promise and how its value could be set at any time, in opposite to Future, which value is only readable.

Suppose you have a mom and you ask her for money.

Now , you trick your mom into creating you a promise of eventual donation, she gives you that promise object, but she is not really in rash to fulfill it yet:

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

You are happy, you run to thank you your mom:

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

But your father interferes and generally aborts mom's plans and completes the promise (sets its value!) with far lesser contribution, as fathers do, very resolutely, while mom is slowly opening her purse (notice Thread.sleep(...)) :

promise.complete(10); 

Output of that is:

Thank you mom for $10

Mom's promise was created , but waited for some "completion" event.

CompletableFuture<Integer> promise...

You created such event, accepting her promise and announcing your plans to thank your mom:

promise.thenAccept...

At this moment mom started open her purse...but very slow...

and father interfered much faster and completed the promise instead of your mom:

promise.complete(10);

Have you noticed an executor that I wrote explicitly? Interesting, that if you use default implicit executor instead (commonPool) and father is not at home, only mom with her "slow purse", then her promise will be only completed, if the program lives more time than mom needs to get money from the purse. I mean default executor acts in a way of "daemon". I have not found a good description of this fact...

查看更多
Rolldiameter
4楼-- · 2019-01-16 00:17

(I'm not completely happy with the answers so far, so here is my attempt...)

I think that Kevin Wright's comment ("You can make a Promise and it's up to you to keep it. When someone else makes you a promise you must wait to see if they honour it in the Future") summarizes it pretty well, but some explanation can be useful.

Futures and promises are pretty similar concepts, the difference is that a future is a read-only container for a result that does not yet exist, while a promise can be written (normally only once). The Java 8 CompletableFuture and the Guava SettableFuture can be thought of as promises, because their value can be set ("completed"), but they also implement the Future interface, therefore there is no difference for the client.

The result of the future will be set by "someone else" - by the result of an asynchronous computation. Note how FutureTask - a classic future - must be initialized with a Callable or Runnable, there is no no-argument constructor, and both Future and FutureTask are read-only from the outside (the set methods of FutureTask are protected). The value will be set to the result of the computation from the inside.

On the other hand, the result of a promise can be set by "you" (or in fact by anybody) anytime because it has a public setter method. Both CompletableFuture and SettableFuture can be created without any task, and their value can be set at any time. You send a promise to the client code, and fulfill it later as you wish.

Note that CompletableFuture is not a "pure" promise, it can be initialized with a task just like FutureTask, and its most useful feature is the unrelated chaining of processing steps.

Also note that a promise does not have to be a subtype of future and it does not have to be the same object. In Scala a Future object is created by an asynchronous computation or by a different Promise object. In C++ the situation is similar: the promise object is used by the producer and the future object by the consumer. The advantage of this separation is that the client cannot set the value of the future.

Both Spring and EJB 3.1 have an AsyncResult class, which is similar to the Scala/C++ promises. AsyncResult does implement Future but this is not the real future: asynchronous methods in Spring/EJB return a different, read-only Future object through some background magic, and this second "real" future can be used by the client to access the result.

查看更多
相关推荐>>
5楼-- · 2019-01-16 00:18

According to this discussion, Promise has finally been called CompletableFuture for inclusion in Java 8, and its javadoc explains:

A Future that may be explicitly completed (setting its value and status), and may be used as a CompletionStage, supporting dependent functions and actions that trigger upon its completion.

An example is also given on the list:

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

Note that the final API is slightly different but allows similar asynchronous execution:

CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);
查看更多
我命由我不由天
6楼-- · 2019-01-16 00:32

No set method in Future interface, only get method, so it is read-only. About CompletableFuture, this article maybe helpful. completablefuture

查看更多
劳资没心,怎么记你
7楼-- · 2019-01-16 00:35

For client code, Promise is for observing or attaching callback when a result is available, whereas Future is to wait for result and then continue. Theoretically anything which is possible to do with futures what can done with promises, but due to the style difference, the resultant API for promises in different languages make chaining easier.

查看更多
登录 后发表回答