CompletableFuture
Remi Forax
forax at univ-mlv.fr
Tue Nov 27 14:01:28 PST 2012
On 11/27/2012 06:20 PM, Doug Lea wrote:
>
> This is not part of lambda-libs proper, but is a lambda-dependent
> j.u.c class -- the last item of our jsr166 JDK8 todo list (see JEP155
> http://openjdk.java.net/jeps/155), so it would be great to get
> some preliminary feedback on this here.
>
> Thanks especially to Sam for bugging me to get this going.
>
> This is the class that has variously been called FutureValue,
> SettableFuture, Promise, and other names. Since the focus is
> on possibly-async completions/callbacks, unifying the
> terminology around "complete" gives a big hint about usage.
> In some senses it is the less geeky, more limited, non-FJ variant
> of CountedCompleter (that I confess to loving much more
> but is vastly less obvious to use effectively.)
>
>
>
> /**
> * A {@link Future} that may be explicitly completed (thus setting its
> * value and status), and may support dependent CompletableFutures
> * that trigger upon its completion.
> */
> public class CompletableFuture<T> implements Future<T> {
> // yes, a single, concrete class.
> // todo: wildcards
here is the version with the wildcards :)
>
> /**
> * Creates a new incomplete CompletableFuture.
> */
> public CompletableFuture();
>
> /**
> * If not already completed, sets the value returned by get() and
> * related methods to the given value.
> *
> * @return false if already done.
> */
> public boolean complete(T value);
>
> /**
> * If not already completed, causes invocations of get() to
> * throw the given exception.
> *
> * @return false if already done.
> */
> public boolean completeExceptionally(Throwable ex);
>
> // cascading completions
>
> /**
> * Creates and returns a CompletableFuture that is completed with
> * the result of the given function of this CompletableFuture's
> * result if/when this completes normally.
> *
> * @return the new CompletableFuture
> */
> public <U> CompletableFuture<U> then(Function<? super T,? extends
> U> fn);
>
> /**
> * Creates and Returns a CompletableFuture that is completed with
> * the result of the given function of this and the other given
> * CompletableFuture's results if/when both complete normally.
> *
> * @return the new CompletableFuture
> */
> public <U,V> CompletableFuture<V> and(CompletableFuture<? extends
> U> x, BiFunction<? super T,? super U,? extends V> fn);
>
> /**
> * Creates and returns a CompletableFuture that is completed with
> * the result of the given function of either this or the other
> * given CompletableFuture's results if/when either complete
> * normally.
> *
> * @return the new CompletableFuture
> */
> public <U> CompletableFuture<U> or(CompletableFuture<? extends T>
> x, BiFunction<? super T,? super T, ? extends U> fn);
>
> // terminal completions
>
> /**
> * Performs the given action with the result of this
> * CompletableFuture if/when it completes normally.
> *
> * @return this CompletableFuture, for convenience
> */
> public CompletableFuture<T> then(Block<? super T> action);
The result should be a Completable<?> not a CompletableFuture<T>, right ?
>
> /**
> * Performs the given action with the result of the given function
> * of this and the other given CompletableFuture's results if/when
> * both complete normally.
> *
> * @return this CompletableFuture, for convenience
> */
> public <U> CompletableFuture<T> and(CompletableFuture<? extends U>
> x, BiBlock<? super T, ? super U> action);
See above.
Also, I think that we decided (correct me if I'm wrong) to not use the
result type of a lambda to disambiguate overloads,
so completable.and(completable2, (a,b) -> foo(a, b)) is ambiguous.
>
> /**
> * Performs the given action with the result of the given function
> * of either this or the other given CompletableFuture's results
> * if/when either complete normally.
> *
> * @return this CompletableFuture, for convenience
> */
> public CompletableFuture<T> or(CompletableFuture<? extends T> x,
> BiBlock<? super T, ? super T> action);
see above
>
> /**
> * Performs the given action with the exception triggering this
> * CompletableFuture's completion if/when it completes exceptionally.
> *
> * @return this CompletableFuture, for convenience
> */
> public CompletableFuture<T> exceptionally(Block<Throwable> action);
>
> // extracting results
>
> /**
> * Returns the value when complete, or throws an (unchecked)
> * exception if completed exceptionally. (The checked exception
> * variant is available using the timed form of get.)
> */
> public T get(); // overrides Future.get to tunnel exceptions
>
> /**
> * Returns the value if it is ready, else the given valueIfAbsent.
> */
> public T getNow(T valueIfAbsent);
I prefer T getNow(Supplier<? extends T> supplierOfValueIfAbsent);
>
> // from Future
> public T get(long timeout, TimeUnit unit)
> throws InterruptedException, ExecutionException,
> TimeoutException;
>
> // misc
>
> /**
> * Whether or not already completed, sets the value returned by
> * subsequent invocations of get() and related methods to the
> * given value.
> */
> public void force(T value);
The semantics of complete and force regarding thread that is already
waiting on get() is not clear for me.
>
> public boolean cancel(boolean mayInterruptIfRunning);
>
> public boolean isCancelled();
>
> public boolean isDone(); // also alias isComplete?
> }
cheers,
Rémi
More information about the lambda-libs-spec-observers
mailing list