Package javascalautils.concurrent
Interface Future<T>
-
- Type Parameters:
T
- The type this Future will hold as result
public interface Future<T>
A Future that will hold the result of an asynchronous computation.
The Future is paired with an instance ofPromise
which is also the way to get hold of a Future.
One can see a Future as a holder for a value-to-be, not yet available but accessible sometime in the future.
The preferred way to get hold of the value-to-be is to register a listener on any of the provided listener types since this allows for asynchronous non-blocking operations. It is possible to register multiple listeners to several/same listener type.
One can register a listener both before and after a Future has been completed.
Should the Future already be completed when the listener is added it is fired immediately.
The guarantee is that a listener is only fired once.
All operations on this class are non-blocking, i.e. allowing for proper asynchronous/non-blocking programming patterns.
With one exception, for situations where it is necessary to maintain synchronous/blocking behavior the methodresult(long, TimeUnit)
is provided.
For real short and consistent programming one can use theapply(ThrowableFunction0)
method to provide a function that will be executed in the future.
The result of the function will be reported to the Future returned by the method.Future<Integer> resultSuccess = Future.apply(() -> 9 / 3); // The Future will at some point contain: Success(3) Future<Integer> resultFailure = Future.apply(() -> 9 / 0); // The Future will at some point contain: Failure(ArithmeticException)
- Since:
- 1.2
-
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description static <T> Future<T>
apply(ThrowableFunction0<T> function)
Allows for easy creation of asynchronous computations that will be executed in the future.static <T> Future<T>
apply(ThrowableFunction0<T> function, Executor executor)
Allows for easy creation of asynchronous computations that will be executed in the future.static <T> Future<T>
failed(java.lang.Throwable throwable)
Creates a failed Future with the provided Throwable.Future<T>
filter(java.util.function.Predicate<T> predicate)
Creates a newFuture
that will filter the successful value of this instance once it is completed.<R> Future<R>
flatMap(ThrowableFunction1<T,Future<R>> function)
Creates a newFuture
that will hold the mapped successful value of this instance once it is completed.void
forEach(java.util.function.Consumer<T> consumer)
Asynchronously processes the value in the Future once it is available.static <T> Future<T>
fromTry(Try<T> result)
Creates a completed Future with the provided Try.boolean
isCompleted()
Check if this Future is completed, with a value or an exception.<R> Future<R>
map(ThrowableFunction1<T,R> function)
Creates a newFuture
that will hold the mapped successful value of this instance once it is completed.void
onComplete(java.util.function.Consumer<Try<T>> completeHandler)
Register a handler to be invoked if the Future gets completed with a value or a failure.void
onFailure(java.util.function.Consumer<java.lang.Throwable> failureHandler)
Register a handler to be invoked if the Future gets completed with an exception.void
onSuccess(java.util.function.Consumer<T> successHandler)
Register a handler to be invoked if the Future gets completed with a value.Future<T>
ready(long duration, java.util.concurrent.TimeUnit timeUnit)
Blocks and waits for this Future to complete.default Future<T>
ready(java.time.Duration duration)
Blocks and waits for this Future to complete.Future<T>
recover(ThrowableFunction1<java.lang.Throwable,T> recoverFunction)
T
result(long duration, java.util.concurrent.TimeUnit timeUnit)
Blocks and waits for this Future to complete.default T
result(java.time.Duration duration)
Blocks and waits for this Future to complete.static <T> Future<java.util.stream.Stream<T>>
sequence(java.util.stream.Stream<Future<T>> stream)
Turns a Stream of Futures into a single Future containing a Stream with all the results from the Futures.static <T> Future<T>
successful(T value)
Creates a successful Future with the provided value.<R> Future<R>
transform(ThrowableFunction1<T,R> onSuccess, ThrowableFunction1<java.lang.Throwable,java.lang.Throwable> onFailure)
Creates a newFuture
that will hold the transformed successful value of this instance once it is completed.static <T,R>
Future<java.util.stream.Stream<R>>traverse(java.util.stream.Stream<T> stream, java.util.function.Function<T,Future<R>> function)
Takes a Stream of values and applies the provided function to them in parallel resulting in a Future containing a Stream with the mapped values.Option<Try<T>>
value()
The current (completed or not) value of the future.
-
-
-
Method Detail
-
apply
static <T> Future<T> apply(ThrowableFunction0<T> function)
Allows for easy creation of asynchronous computations that will be executed in the future.
The method will use theExecutors.getDefault()
method to get hold of the defaultExecutor
to use for executing the provided job.
Simple examples:Future<Integer> resultSuccess = Future.apply(() -> 9 / 3); // The Future will at some point contain: Success(3) Future<Integer> resultFailure = Future.apply(() -> 9 / 0); // The Future will at some point contain: Failure(ArithmeticException)
- Type Parameters:
T
- The type for the Future- Parameters:
function
- The function to render either the value T or raise an exception.- Returns:
- The future that will hold the result provided by the function
- Since:
- 1.3
-
apply
static <T> Future<T> apply(ThrowableFunction0<T> function, Executor executor)
Allows for easy creation of asynchronous computations that will be executed in the future.
The method will use the providedExecutor
for executing the provided job.
Simple examples:Future<Integer> resultSuccess = Future.apply(() -> 9 / 3, someExecutor); // The Future will at some point contain: Success(3) Future<Integer> resultFailure = Future.apply(() -> 9 / 0, someExecutor); // The Future will at some point contain: Failure(ArithmeticException)
- Type Parameters:
T
- The type for the Future- Parameters:
function
- The function to render either the value T or raise an exception.executor
- The executor to use to compute/execute the Future holding the provided function- Returns:
- The future that will hold the result provided by the function
- Since:
- 1.4
-
failed
static <T> Future<T> failed(java.lang.Throwable throwable)
Creates a failed Future with the provided Throwable.- Type Parameters:
T
- The type for the Future- Parameters:
throwable
- The throwable to complete the Future with.- Returns:
- The completed Future holding the provided Throwable
- Since:
- 1.5
-
successful
static <T> Future<T> successful(T value)
Creates a successful Future with the provided value.- Type Parameters:
T
- The type for the Future- Parameters:
value
- The value to complete the Future with.- Returns:
- The completed Future holding the provided value
- Since:
- 1.5
-
sequence
static <T> Future<java.util.stream.Stream<T>> sequence(java.util.stream.Stream<Future<T>> stream)
Turns a Stream of Futures into a single Future containing a Stream with all the results from the Futures.
Allows for easy management of multiple Futures.
Note, should any Future in the Stream fail the entire sequence fails.
An empty input Stream will result in a Future containing an empty result Stream.- Type Parameters:
T
- The type for the Stream in the resulting Future- Parameters:
stream
- The Stream with Futures- Returns:
- A single Future containing the Stream of results
- Since:
- 1.5
-
traverse
static <T,R> Future<java.util.stream.Stream<R>> traverse(java.util.stream.Stream<T> stream, java.util.function.Function<T,Future<R>> function)
Takes a Stream of values and applies the provided function to them in parallel resulting in a Future containing a Stream with the mapped values.
Can be used to run a mapping operation in parallel e.g.:import static javascalautils.FutureCompanion.Future; Stream<String> stream = ...; // Stream with strings Future<Stream<Integer>> future = Future.traverse(stream, v -> Future(() -> v.length()));
- Type Parameters:
T
- The type for the input StreamR
- The type for the Stream in the resulting Future- Parameters:
stream
- The Stream with valuesfunction
- The function to be applied to all values of the Stream- Returns:
- A single Future containing the Stream of results
- Since:
- 1.5
-
isCompleted
boolean isCompleted()
Check if this Future is completed, with a value or an exception.- Returns:
true
if completed,false
otherwise.
-
value
Option<Try<T>> value()
The current (completed or not) value of the future.
This is a non-blocking method, it will return the current state/value of the Future.
There are three possible outcomes:- Returns:
- An
Option
with the result.
-
onFailure
void onFailure(java.util.function.Consumer<java.lang.Throwable> failureHandler)
Register a handler to be invoked if the Future gets completed with an exception.
If the Future has already been completed the notification will happen in the current thread.
Multiple handlers can be registered, without any guarantee of notification order.
Each individual event handler will only be invoked once.- Parameters:
failureHandler
- Consumer to invoke.
-
onSuccess
void onSuccess(java.util.function.Consumer<T> successHandler)
Register a handler to be invoked if the Future gets completed with a value.
If the Future has already been completed the notification will happen in the current thread.
Multiple handlers can be registered, without any guarantee of notification order.
Each individual event handler will only be invoked once.- Parameters:
successHandler
- Consumer to invoke.
-
onComplete
void onComplete(java.util.function.Consumer<Try<T>> completeHandler)
Register a handler to be invoked if the Future gets completed with a value or a failure.
If the Future has already been completed the notification will happen in the current thread.
Multiple handlers can be registered, without any guarantee of notification order.
Each individual event handler will only be invoked once.- Parameters:
completeHandler
- Consumer to invoke.
-
forEach
void forEach(java.util.function.Consumer<T> consumer)
Asynchronously processes the value in the Future once it is available.
Only successful Futures are reported to the consumer.
This is pretty much the same asonSuccess(Consumer)
but is here for completion keeping a consistent look and feel.- Parameters:
consumer
- The consumer to digest the result
-
map
<R> Future<R> map(ThrowableFunction1<T,R> function)
Creates a newFuture
that will hold the mapped successful value of this instance once it is completed.
Unsuccessful Futures will not be mapped, they are kept unsuccessful as they are.- Type Parameters:
R
- The type for the value held by the mapped future- Parameters:
function
- The function to apply- Returns:
- The mapped Future
-
flatMap
<R> Future<R> flatMap(ThrowableFunction1<T,Future<R>> function)
Creates a newFuture
that will hold the mapped successful value of this instance once it is completed.
Unsuccessful Futures will not be mapped, they are kept unsuccessful as they are.- Type Parameters:
R
- The type for the value held by the mapped future- Parameters:
function
- The function to apply- Returns:
- The mapped Future
-
filter
Future<T> filter(java.util.function.Predicate<T> predicate)
Creates a newFuture
that will filter the successful value of this instance once it is completed.
The possible outcomes are:- This Future is successful -> predicate matches -> The filtered future is completed with the value.
- This Future is successful -> predicate fails -> The filtered future is failed with NoSuchElementException.
- This Future is failure -> The failure is passed on to the filtered Future.
- Parameters:
predicate
- The predicate to apply- Returns:
- The filtered Future
-
transform
<R> Future<R> transform(ThrowableFunction1<T,R> onSuccess, ThrowableFunction1<java.lang.Throwable,java.lang.Throwable> onFailure)
Creates a newFuture
that will hold the transformed successful value of this instance once it is completed.
Successful futures are transformed with the onSuccess function and unsuccessful/failure futures are transformed with onFailure.- Type Parameters:
R
- The type for the value held by the mapped future- Parameters:
onSuccess
- The function to apply on a 'successful' resultonFailure
- The function to apply on a 'failure' result- Returns:
- The mapped Future
- Since:
- 1.3
-
recover
Future<T> recover(ThrowableFunction1<java.lang.Throwable,T> recoverFunction)
Creates a newFuture
that in case thisFuture
is a 'failure' will apply the function to recover the 'failure' to a 'success'.
Should thisFuture
be a 'success' the value is propagated as-is.
E.g.Future<String> future = ... Future<String> recovered = future.recover(t -> t.getMessage());
- Parameters:
recoverFunction
- The function to apply in case of a 'failure'- Returns:
- The recovered Future
- Since:
- 1.3
-
result
T result(long duration, java.util.concurrent.TimeUnit timeUnit) throws java.lang.Throwable, java.util.concurrent.TimeoutException
Blocks and waits for this Future to complete.
Returns the result of a successful Future or throws the exception in case of a failure.
The methods blocks for at most the provided duration.
If the Future is already completed the method returns immediately.- Parameters:
duration
- The duration to blocktimeUnit
- The unit for the duration- Returns:
- The result in case successful
- Throws:
java.lang.Throwable
- The error reported in case of a failurejava.util.concurrent.TimeoutException
- In case the waiting time is passed
-
result
default T result(java.time.Duration duration) throws java.lang.Throwable, java.util.concurrent.TimeoutException
Blocks and waits for this Future to complete.
Returns the result of a successful Future or throws the exception in case of a failure.
The methods blocks for at most the provided duration.
If the Future is already completed the method returns immediately.- Parameters:
duration
- The duration to block- Returns:
- The result in case successful
- Throws:
java.lang.Throwable
- The error reported in case of a failurejava.util.concurrent.TimeoutException
- In case the waiting time is passed- Since:
- 1.8
-
ready
Future<T> ready(long duration, java.util.concurrent.TimeUnit timeUnit) throws java.util.concurrent.TimeoutException, java.lang.InterruptedException
Blocks and waits for this Future to complete.
As opposed toresult
this method will not return the value or throw the exception of the Future.
The method will upon completion returns this.
The purpose of the method is to provide a blocking mechanism waiting for the Future to complete.
Any action on the Future's result is then left to the developer to manage.- Parameters:
duration
- The duration to blocktimeUnit
- The unit for the duration- Returns:
- this if the Future completes within the specified time
- Throws:
java.util.concurrent.TimeoutException
- In case the waiting time is passedjava.lang.InterruptedException
- In case the thread gets interrupted during the wait- Since:
- 1.8
-
ready
default Future<T> ready(java.time.Duration duration) throws java.util.concurrent.TimeoutException, java.lang.InterruptedException
Blocks and waits for this Future to complete.
As opposed toresult
this method will not return the value or throw the exception of the Future.
The method will upon completion returns this.
The purpose of the method is to provide a blocking mechanism waiting for the Future to complete.
Any action on the Future's result is then left to the developer to manage.- Parameters:
duration
- The duration to block- Returns:
- this if the Future completes within the specified time
- Throws:
java.util.concurrent.TimeoutException
- In case the waiting time is passedjava.lang.InterruptedException
- In case the thread gets interrupted during the wait- Since:
- 1.8
-
-