@GwtCompatible(emulated=true) public final class Futures extends Object
Future
interface.
Many of these methods use the ListenableFuture
API; consult the Guava User Guide
article on ListenableFuture
.
The main purpose of ListenableFuture
is to help you chain together a graph of
asynchronous operations. You can chain them together manually with calls to methods like Futures.transform
, but you will often
find it easier to use a framework. Frameworks automate the process, often adding features like
monitoring, debugging, and cancellation. Examples of frameworks include:
If you do chain your operations manually, you may want to use FluentFuture
.
Modifier and Type | Class and Description |
---|---|
static class |
Futures.FutureCombiner<V>
A helper to create a new
ListenableFuture whose result is generated from a combination
of input futures. |
Modifier and Type | Method and Description |
---|---|
static <V> void |
addCallback(ListenableFuture<V> future,
FutureCallback<? super V> callback,
Executor executor)
Registers separate success and failure callbacks to be run when the
Future 's
computation is complete or, if the
computation is already complete, immediately. |
static <V> ListenableFuture<List<V>> |
allAsList(Iterable<? extends ListenableFuture<? extends V>> futures)
Creates a new
ListenableFuture whose value is a list containing the values of all its
input futures, if all succeed. |
static <V> ListenableFuture<List<V>> |
allAsList(ListenableFuture<? extends V>... futures)
Creates a new
ListenableFuture whose value is a list containing the values of all its
input futures, if all succeed. |
static <V,X extends Throwable> |
catching(ListenableFuture<? extends V> input,
Class<X> exceptionType,
Function<? super X,? extends V> fallback,
Executor executor)
Returns a
Future whose result is taken from the given primary input or, if the
primary input fails with the given exceptionType , from the result provided by the
fallback . |
static <V,X extends Throwable> |
catchingAsync(ListenableFuture<? extends V> input,
Class<X> exceptionType,
AsyncFunction<? super X,? extends V> fallback,
Executor executor)
Returns a
Future whose result is taken from the given primary input or, if the
primary input fails with the given exceptionType , from the result provided by the
fallback . |
static <V,X extends Exception> |
getChecked(Future<V> future,
Class<X> exceptionClass)
Returns the result of
Future.get() , converting most exceptions to a new instance of the
given checked exception type. |
static <V,X extends Exception> |
getChecked(Future<V> future,
Class<X> exceptionClass,
Duration timeout)
Returns the result of
Future.get(long, TimeUnit) , converting most exceptions to a new
instance of the given checked exception type. |
static <V,X extends Exception> |
getChecked(Future<V> future,
Class<X> exceptionClass,
long timeout,
TimeUnit unit)
Returns the result of
Future.get(long, TimeUnit) , converting most exceptions to a new
instance of the given checked exception type. |
static <V> V |
getDone(Future<V> future)
Returns the result of the input
Future , which must have already completed. |
static <V> V |
getUnchecked(Future<V> future)
Returns the result of calling
Future.get() uninterruptibly on a task known not to throw
a checked exception. |
static <V> ListenableFuture<V> |
immediateCancelledFuture()
Creates a
ListenableFuture which is cancelled immediately upon construction, so that
isCancelled() always returns true . |
static <V> ListenableFuture<V> |
immediateFailedFuture(Throwable throwable)
Returns a
ListenableFuture which has an exception set immediately upon construction. |
static <V> ListenableFuture<V> |
immediateFuture(V value)
Creates a
ListenableFuture which has its value set immediately upon construction. |
static <T> ImmutableList<ListenableFuture<T>> |
inCompletionOrder(Iterable<? extends ListenableFuture<? extends T>> futures)
Returns a list of delegate futures that correspond to the futures received in the order that
they complete.
|
static <I,O> Future<O> |
lazyTransform(Future<I> input,
Function<? super I,? extends O> function)
Like
transform(ListenableFuture, Function, Executor) except that the transformation
function is invoked on each call to get() on the returned future. |
static <V> ListenableFuture<V> |
nonCancellationPropagating(ListenableFuture<V> future)
Returns a
ListenableFuture whose result is set from the supplied future when it
completes. |
static <O> ListenableFuture<O> |
scheduleAsync(AsyncCallable<O> callable,
Duration delay,
ScheduledExecutorService executorService)
Schedules
callable on the specified executor , returning a Future . |
static <O> ListenableFuture<O> |
scheduleAsync(AsyncCallable<O> callable,
long delay,
TimeUnit timeUnit,
ScheduledExecutorService executorService)
Schedules
callable on the specified executor , returning a Future . |
static <O> ListenableFuture<O> |
submitAsync(AsyncCallable<O> callable,
Executor executor)
Executes
callable on the specified executor , returning a Future . |
static <V> ListenableFuture<List<V>> |
successfulAsList(Iterable<? extends ListenableFuture<? extends V>> futures)
Creates a new
ListenableFuture whose value is a list containing the values of all its
successful input futures. |
static <V> ListenableFuture<List<V>> |
successfulAsList(ListenableFuture<? extends V>... futures)
Creates a new
ListenableFuture whose value is a list containing the values of all its
successful input futures. |
static <I,O> ListenableFuture<O> |
transform(ListenableFuture<I> input,
Function<? super I,? extends O> function,
Executor executor)
Returns a new
Future whose result is derived from the result of the given Future . |
static <I,O> ListenableFuture<O> |
transformAsync(ListenableFuture<I> input,
AsyncFunction<? super I,? extends O> function,
Executor executor)
Returns a new
Future whose result is asynchronously derived from the result of the
given Future . |
static <V> Futures.FutureCombiner<V> |
whenAllComplete(Iterable<? extends ListenableFuture<? extends V>> futures)
Creates a
Futures.FutureCombiner that processes the completed futures whether or not they're
successful. |
static <V> Futures.FutureCombiner<V> |
whenAllComplete(ListenableFuture<? extends V>... futures)
Creates a
Futures.FutureCombiner that processes the completed futures whether or not they're
successful. |
static <V> Futures.FutureCombiner<V> |
whenAllSucceed(Iterable<? extends ListenableFuture<? extends V>> futures)
Creates a
Futures.FutureCombiner requiring that all passed in futures are successful. |
static <V> Futures.FutureCombiner<V> |
whenAllSucceed(ListenableFuture<? extends V>... futures)
Creates a
Futures.FutureCombiner requiring that all passed in futures are successful. |
static <V> ListenableFuture<V> |
withTimeout(ListenableFuture<V> delegate,
Duration time,
ScheduledExecutorService scheduledExecutor)
Returns a future that delegates to another but will finish early (via a
TimeoutException wrapped in an ExecutionException ) if the specified duration expires. |
static <V> ListenableFuture<V> |
withTimeout(ListenableFuture<V> delegate,
long time,
TimeUnit unit,
ScheduledExecutorService scheduledExecutor)
Returns a future that delegates to another but will finish early (via a
TimeoutException wrapped in an ExecutionException ) if the specified duration expires. |
public static <V> ListenableFuture<V> immediateFuture(V value)
ListenableFuture
which has its value set immediately upon construction. The
getters just return the value. This Future
can't be canceled or timed out and its
isDone()
method always returns true
.public static <V> ListenableFuture<V> immediateFailedFuture(Throwable throwable)
ListenableFuture
which has an exception set immediately upon construction.
The returned Future
can't be cancelled, and its isDone()
method always
returns true
. Calling get()
will immediately throw the provided Throwable
wrapped in an ExecutionException
.
public static <V> ListenableFuture<V> immediateCancelledFuture()
ListenableFuture
which is cancelled immediately upon construction, so that
isCancelled()
always returns true
.@Beta public static <O> ListenableFuture<O> submitAsync(AsyncCallable<O> callable, Executor executor)
callable
on the specified executor
, returning a Future
.RejectedExecutionException
- if the task cannot be scheduled for execution@Beta @GwtIncompatible public static <O> ListenableFuture<O> scheduleAsync(AsyncCallable<O> callable, Duration delay, ScheduledExecutorService executorService)
callable
on the specified executor
, returning a Future
.RejectedExecutionException
- if the task cannot be scheduled for execution@Beta @GwtIncompatible public static <O> ListenableFuture<O> scheduleAsync(AsyncCallable<O> callable, long delay, TimeUnit timeUnit, ScheduledExecutorService executorService)
callable
on the specified executor
, returning a Future
.RejectedExecutionException
- if the task cannot be scheduled for execution@Beta @Partially.GwtIncompatible(value="AVAILABLE but requires exceptionType to be Throwable.class") public static <V,X extends Throwable> ListenableFuture<V> catching(ListenableFuture<? extends V> input, Class<X> exceptionType, Function<? super X,? extends V> fallback, Executor executor)
Future
whose result is taken from the given primary input
or, if the
primary input fails with the given exceptionType
, from the result provided by the
fallback
. Function.apply(F)
is not invoked until the primary input has failed, so
if the primary input succeeds, it is never invoked. If, during the invocation of fallback
, an exception is thrown, this exception is used as the result of the output Future
.
Usage example:
ListenableFuture<Integer> fetchCounterFuture = ...;
// Falling back to a zero counter in case an exception happens when
// processing the RPC to fetch counters.
ListenableFuture<Integer> faultTolerantFuture = Futures.catching(
fetchCounterFuture, FetchException.class, x -> 0, directExecutor());
When selecting an executor, note that directExecutor
is dangerous in some cases. See
the discussion in the ListenableFuture.addListener
documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
functions passed to this method.
input
- the primary input Future
exceptionType
- the exception type that triggers use of fallback
. The exception
type is matched against the input's exception. "The input's exception" means the cause of
the ExecutionException
thrown by input.get()
or, if get()
throws a
different kind of exception, that exception itself. To avoid hiding bugs and other
unrecoverable errors, callers should prefer more specific types, avoiding Throwable.class
in particular.fallback
- the Function
to be called if input
fails with the expected
exception type. The function's argument is the input's exception. "The input's exception"
means the cause of the ExecutionException
thrown by input.get()
or, if
get()
throws a different kind of exception, that exception itself.executor
- the executor that runs fallback
if input
fails@Beta @Partially.GwtIncompatible(value="AVAILABLE but requires exceptionType to be Throwable.class") public static <V,X extends Throwable> ListenableFuture<V> catchingAsync(ListenableFuture<? extends V> input, Class<X> exceptionType, AsyncFunction<? super X,? extends V> fallback, Executor executor)
Future
whose result is taken from the given primary input
or, if the
primary input fails with the given exceptionType
, from the result provided by the
fallback
. AsyncFunction.apply(I)
is not invoked until the primary input has
failed, so if the primary input succeeds, it is never invoked. If, during the invocation of
fallback
, an exception is thrown, this exception is used as the result of the output
Future
.
Usage examples:
ListenableFuture<Integer> fetchCounterFuture = ...;
// Falling back to a zero counter in case an exception happens when
// processing the RPC to fetch counters.
ListenableFuture<Integer> faultTolerantFuture = Futures.catchingAsync(
fetchCounterFuture, FetchException.class, x -> immediateFuture(0), directExecutor());
The fallback can also choose to propagate the original exception when desired:
ListenableFuture<Integer> fetchCounterFuture = ...;
// Falling back to a zero counter only in case the exception was a
// TimeoutException.
ListenableFuture<Integer> faultTolerantFuture = Futures.catchingAsync(
fetchCounterFuture,
FetchException.class,
e -> {
if (omitDataOnFetchFailure) {
return immediateFuture(0);
}
throw e;
},
directExecutor());
When selecting an executor, note that directExecutor
is dangerous in some cases. See
the discussion in the ListenableFuture.addListener
documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
functions passed to this method. (Specifically, directExecutor
functions should avoid
heavyweight operations inside AsyncFunction.apply
. Any heavyweight operations should
occur in other threads responsible for completing the returned Future
.)
input
- the primary input Future
exceptionType
- the exception type that triggers use of fallback
. The exception
type is matched against the input's exception. "The input's exception" means the cause of
the ExecutionException
thrown by input.get()
or, if get()
throws a
different kind of exception, that exception itself. To avoid hiding bugs and other
unrecoverable errors, callers should prefer more specific types, avoiding Throwable.class
in particular.fallback
- the AsyncFunction
to be called if input
fails with the expected
exception type. The function's argument is the input's exception. "The input's exception"
means the cause of the ExecutionException
thrown by input.get()
or, if
get()
throws a different kind of exception, that exception itself.executor
- the executor that runs fallback
if input
failswithFallback
)@Beta @GwtIncompatible public static <V> ListenableFuture<V> withTimeout(ListenableFuture<V> delegate, Duration time, ScheduledExecutorService scheduledExecutor)
TimeoutException
wrapped in an ExecutionException
) if the specified duration expires.
The delegate future is interrupted and cancelled if it times out.
delegate
- The future to delegate to.time
- when to timeout the futurescheduledExecutor
- The executor service to enforce the timeout.@Beta @GwtIncompatible public static <V> ListenableFuture<V> withTimeout(ListenableFuture<V> delegate, long time, TimeUnit unit, ScheduledExecutorService scheduledExecutor)
TimeoutException
wrapped in an ExecutionException
) if the specified duration expires.
The delegate future is interrupted and cancelled if it times out.
delegate
- The future to delegate to.time
- when to timeout the futureunit
- the time unit of the time parameterscheduledExecutor
- The executor service to enforce the timeout.@Beta public static <I,O> ListenableFuture<O> transformAsync(ListenableFuture<I> input, AsyncFunction<? super I,? extends O> function, Executor executor)
Future
whose result is asynchronously derived from the result of the
given Future
. If the given Future
fails, the returned Future
fails with
the same exception (and the function is not invoked).
More precisely, the returned Future
takes its result from a Future
produced
by applying the given AsyncFunction
to the result of the original Future
.
Example usage:
ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
ListenableFuture<QueryResult> queryFuture =
transformAsync(rowKeyFuture, dataService::readFuture, executor);
When selecting an executor, note that directExecutor
is dangerous in some cases. See
the discussion in the ListenableFuture.addListener
documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
functions passed to this method. (Specifically, directExecutor
functions should avoid
heavyweight operations inside AsyncFunction.apply
. Any heavyweight operations should
occur in other threads responsible for completing the returned Future
.)
The returned Future
attempts to keep its cancellation state in sync with that of the
input future and that of the future returned by the chain function. That is, if the returned
Future
is cancelled, it will attempt to cancel the other two, and if either of the
other two is cancelled, the returned Future
will receive a callback in which it will
attempt to cancel itself.
input
- The future to transformfunction
- A function to transform the result of the input future to the result of the
output futureexecutor
- Executor to run the function in.transform
)@Beta public static <I,O> ListenableFuture<O> transform(ListenableFuture<I> input, Function<? super I,? extends O> function, Executor executor)
Future
whose result is derived from the result of the given Future
. If input
fails, the returned Future
fails with the same exception (and
the function is not invoked). Example usage:
ListenableFuture<QueryResult> queryFuture = ...;
ListenableFuture<List<Row>> rowsFuture =
transform(queryFuture, QueryResult::getRows, executor);
When selecting an executor, note that directExecutor
is dangerous in some cases. See
the discussion in the ListenableFuture.addListener
documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
functions passed to this method.
The returned Future
attempts to keep its cancellation state in sync with that of the
input future. That is, if the returned Future
is cancelled, it will attempt to cancel
the input, and if the input is cancelled, the returned Future
will receive a callback
in which it will attempt to cancel itself.
An example use of this method is to convert a serializable object returned from an RPC into a POJO.
input
- The future to transformfunction
- A Function to transform the results of the provided future to the results of
the returned future.executor
- Executor to run the function in.compose
)@Beta @GwtIncompatible public static <I,O> Future<O> lazyTransform(Future<I> input, Function<? super I,? extends O> function)
transform(ListenableFuture, Function, Executor)
except that the transformation
function
is invoked on each call to get()
on the returned future.
The returned Future
reflects the input's cancellation state directly, and any
attempt to cancel the returned Future is likewise passed through to the input Future.
Note that calls to timed get only apply the timeout
to the execution of the underlying Future
, not to the execution of the
transformation function.
The primary audience of this method is callers of transform
who don't have a ListenableFuture
available and do not mind repeated, lazy function evaluation.
input
- The future to transformfunction
- A Function to transform the results of the provided future to the results of
the returned future.@Beta @SafeVarargs public static <V> ListenableFuture<List<V>> allAsList(ListenableFuture<? extends V>... futures)
ListenableFuture
whose value is a list containing the values of all its
input futures, if all succeed.
The list of results is in the same order as the input list.
Canceling this future will attempt to cancel all the component futures, and if any of the provided futures fails or is canceled, this one is, too.
futures
- futures to combine@Beta public static <V> ListenableFuture<List<V>> allAsList(Iterable<? extends ListenableFuture<? extends V>> futures)
ListenableFuture
whose value is a list containing the values of all its
input futures, if all succeed.
The list of results is in the same order as the input list.
Canceling this future will attempt to cancel all the component futures, and if any of the provided futures fails or is canceled, this one is, too.
futures
- futures to combine@Beta @SafeVarargs public static <V> Futures.FutureCombiner<V> whenAllComplete(ListenableFuture<? extends V>... futures)
Futures.FutureCombiner
that processes the completed futures whether or not they're
successful.@Beta public static <V> Futures.FutureCombiner<V> whenAllComplete(Iterable<? extends ListenableFuture<? extends V>> futures)
Futures.FutureCombiner
that processes the completed futures whether or not they're
successful.@Beta @SafeVarargs public static <V> Futures.FutureCombiner<V> whenAllSucceed(ListenableFuture<? extends V>... futures)
Futures.FutureCombiner
requiring that all passed in futures are successful.
If any input fails, the returned future fails immediately.
@Beta public static <V> Futures.FutureCombiner<V> whenAllSucceed(Iterable<? extends ListenableFuture<? extends V>> futures)
Futures.FutureCombiner
requiring that all passed in futures are successful.
If any input fails, the returned future fails immediately.
@Beta public static <V> ListenableFuture<V> nonCancellationPropagating(ListenableFuture<V> future)
ListenableFuture
whose result is set from the supplied future when it
completes. Cancelling the supplied future will also cancel the returned future, but cancelling
the returned future will have no effect on the supplied future.@Beta @SafeVarargs public static <V> ListenableFuture<List<V>> successfulAsList(ListenableFuture<? extends V>... futures)
ListenableFuture
whose value is a list containing the values of all its
successful input futures. The list of results is in the same order as the input list, and if
any of the provided futures fails or is canceled, its corresponding position will contain
null
(which is indistinguishable from the future having a successful value of null
).
Canceling this future will attempt to cancel all the component futures.
futures
- futures to combine@Beta public static <V> ListenableFuture<List<V>> successfulAsList(Iterable<? extends ListenableFuture<? extends V>> futures)
ListenableFuture
whose value is a list containing the values of all its
successful input futures. The list of results is in the same order as the input list, and if
any of the provided futures fails or is canceled, its corresponding position will contain
null
(which is indistinguishable from the future having a successful value of null
).
Canceling this future will attempt to cancel all the component futures.
futures
- futures to combine@Beta public static <T> ImmutableList<ListenableFuture<T>> inCompletionOrder(Iterable<? extends ListenableFuture<? extends T>> futures)
"In the order that they complete" means, for practical purposes, about what you would expect, but there are some subtleties. First, we do guarantee that, if the output future at index n is done, the output future at index n-1 is also done. (But as usual with futures, some listeners for future n may complete before some for future n-1.) However, it is possible, if one input completes with result X and another later with result Y, for Y to come before X in the output future list. (Such races are impossible to solve without global synchronization of all future completions. And they should have little practical impact.)
Cancelling a delegate future propagates to input futures once all the delegates complete, either from cancellation or because an input future has completed. If N futures are passed in, and M delegates are cancelled, the remaining M input futures will be cancelled once N - M of the input futures complete. If all the delegates are cancelled, all the input futures will be too.
public static <V> void addCallback(ListenableFuture<V> future, FutureCallback<? super V> callback, Executor executor)
Future
's
computation is complete or, if the
computation is already complete, immediately.
The callback is run on executor
. There is no guaranteed ordering of execution of
callbacks, but any callback added through this method is guaranteed to be called once the
computation is complete.
Example:
ListenableFuture<QueryResult> future = ...;
Executor e = ...
addCallback(future,
new FutureCallback<QueryResult>() {
public void onSuccess(QueryResult result) {
storeInCache(result);
}
public void onFailure(Throwable t) {
reportError(t);
}
}, e);
When selecting an executor, note that directExecutor
is dangerous in some cases. See
the discussion in the ListenableFuture.addListener
documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
callbacks passed to this method.
For a more general interface to attach a completion listener to a Future
, see addListener
.
future
- The future attach the callback to.callback
- The callback to invoke when future
is completed.executor
- The executor to run callback
when the future completes.@CanIgnoreReturnValue public static <V> V getDone(Future<V> future) throws ExecutionException
Future
, which must have already completed.
The benefits of this method are twofold. First, the name "getDone" suggests to readers that
the Future
is already done. Second, if buggy code calls getDone
on a Future
that is still pending, the program will throw instead of block. This can be important
for APIs like whenAllComplete(...)
.
call(...)
, where it is easy to use a new input from
the call
implementation but forget to add it to the arguments of whenAllComplete
.
If you are looking for a method to determine whether a given Future
is done, use the
instance method Future.isDone()
.
ExecutionException
- if the Future
failed with an exceptionCancellationException
- if the Future
was cancelledIllegalStateException
- if the Future
is not done@Beta @CanIgnoreReturnValue @GwtIncompatible public static <V,X extends Exception> V getChecked(Future<V> future, Class<X> exceptionClass) throws X extends Exception
Future.get()
, converting most exceptions to a new instance of the
given checked exception type. This reduces boilerplate for a common use of Future
in
which it is unnecessary to programmatically distinguish between exception types or to extract
other information from the exception instance.
Exceptions from Future.get
are treated as follows:
ExecutionException
has its cause wrapped in an X
if the cause
is a checked exception, an UncheckedExecutionException
if the cause is a RuntimeException
, or an ExecutionError
if the cause is an Error
.
InterruptedException
is wrapped in an X
(after restoring the
interrupt).
CancellationException
is propagated untouched, as is any other RuntimeException
(though get
implementations are discouraged from throwing such
exceptions).
The overall principle is to continue to treat every checked exception as a checked
exception, every unchecked exception as an unchecked exception, and every error as an error. In
addition, the cause of any ExecutionException
is wrapped in order to ensure that the
new stack trace matches that of the current thread.
Instances of exceptionClass
are created by choosing an arbitrary public constructor
that accepts zero or more arguments, all of type String
or Throwable
(preferring constructors with at least one String
) and calling the constructor via
reflection. If the exception did not already have a cause, one is set by calling Throwable.initCause(Throwable)
on it. If no such constructor exists, an IllegalArgumentException
is thrown.
X
- if get
throws any checked exception except for an ExecutionException
whose cause is not itself a checked exceptionUncheckedExecutionException
- if get
throws an ExecutionException
with a
RuntimeException
as its causeExecutionError
- if get
throws an ExecutionException
with an Error
as its causeCancellationException
- if get
throws a CancellationException
IllegalArgumentException
- if exceptionClass
extends RuntimeException
or
does not have a suitable constructorX extends Exception
get
)@Beta @CanIgnoreReturnValue @GwtIncompatible public static <V,X extends Exception> V getChecked(Future<V> future, Class<X> exceptionClass, Duration timeout) throws X extends Exception
Future.get(long, TimeUnit)
, converting most exceptions to a new
instance of the given checked exception type. This reduces boilerplate for a common use of
Future
in which it is unnecessary to programmatically distinguish between exception
types or to extract other information from the exception instance.
Exceptions from Future.get
are treated as follows:
ExecutionException
has its cause wrapped in an X
if the cause
is a checked exception, an UncheckedExecutionException
if the cause is a RuntimeException
, or an ExecutionError
if the cause is an Error
.
InterruptedException
is wrapped in an X
(after restoring the
interrupt).
TimeoutException
is wrapped in an X
.
CancellationException
is propagated untouched, as is any other RuntimeException
(though get
implementations are discouraged from throwing such
exceptions).
The overall principle is to continue to treat every checked exception as a checked
exception, every unchecked exception as an unchecked exception, and every error as an error. In
addition, the cause of any ExecutionException
is wrapped in order to ensure that the
new stack trace matches that of the current thread.
Instances of exceptionClass
are created by choosing an arbitrary public constructor
that accepts zero or more arguments, all of type String
or Throwable
(preferring constructors with at least one String
) and calling the constructor via
reflection. If the exception did not already have a cause, one is set by calling Throwable.initCause(Throwable)
on it. If no such constructor exists, an IllegalArgumentException
is thrown.
X
- if get
throws any checked exception except for an ExecutionException
whose cause is not itself a checked exceptionUncheckedExecutionException
- if get
throws an ExecutionException
with a
RuntimeException
as its causeExecutionError
- if get
throws an ExecutionException
with an Error
as its causeCancellationException
- if get
throws a CancellationException
IllegalArgumentException
- if exceptionClass
extends RuntimeException
or
does not have a suitable constructorX extends Exception
@Beta @CanIgnoreReturnValue @GwtIncompatible public static <V,X extends Exception> V getChecked(Future<V> future, Class<X> exceptionClass, long timeout, TimeUnit unit) throws X extends Exception
Future.get(long, TimeUnit)
, converting most exceptions to a new
instance of the given checked exception type. This reduces boilerplate for a common use of
Future
in which it is unnecessary to programmatically distinguish between exception
types or to extract other information from the exception instance.
Exceptions from Future.get
are treated as follows:
ExecutionException
has its cause wrapped in an X
if the cause
is a checked exception, an UncheckedExecutionException
if the cause is a RuntimeException
, or an ExecutionError
if the cause is an Error
.
InterruptedException
is wrapped in an X
(after restoring the
interrupt).
TimeoutException
is wrapped in an X
.
CancellationException
is propagated untouched, as is any other RuntimeException
(though get
implementations are discouraged from throwing such
exceptions).
The overall principle is to continue to treat every checked exception as a checked
exception, every unchecked exception as an unchecked exception, and every error as an error. In
addition, the cause of any ExecutionException
is wrapped in order to ensure that the
new stack trace matches that of the current thread.
Instances of exceptionClass
are created by choosing an arbitrary public constructor
that accepts zero or more arguments, all of type String
or Throwable
(preferring constructors with at least one String
) and calling the constructor via
reflection. If the exception did not already have a cause, one is set by calling Throwable.initCause(Throwable)
on it. If no such constructor exists, an IllegalArgumentException
is thrown.
X
- if get
throws any checked exception except for an ExecutionException
whose cause is not itself a checked exceptionUncheckedExecutionException
- if get
throws an ExecutionException
with a
RuntimeException
as its causeExecutionError
- if get
throws an ExecutionException
with an Error
as its causeCancellationException
- if get
throws a CancellationException
IllegalArgumentException
- if exceptionClass
extends RuntimeException
or
does not have a suitable constructorX extends Exception
get
and with different parameter order)@CanIgnoreReturnValue public static <V> V getUnchecked(Future<V> future)
Future.get()
uninterruptibly on a task known not to throw
a checked exception. This makes Future
more suitable for lightweight, fast-running
tasks that, barring bugs in the code, will not fail. This gives it exception-handling behavior
similar to that of ForkJoinTask.join
.
Exceptions from Future.get
are treated as follows:
ExecutionException
has its cause wrapped in an UncheckedExecutionException
(if the cause is an Exception
) or ExecutionError
(if the cause is an Error
).
InterruptedException
causes a retry of the get
call. The interrupt is
restored before getUnchecked
returns.
CancellationException
is propagated untouched. So is any other RuntimeException
(get
implementations are discouraged from throwing such
exceptions).
The overall principle is to eliminate all checked exceptions: to loop to avoid InterruptedException
, to pass through CancellationException
, and to wrap any exception
from the underlying computation in an UncheckedExecutionException
or ExecutionError
.
For an uninterruptible get
that preserves other exceptions, see Uninterruptibles.getUninterruptibly(Future)
.
UncheckedExecutionException
- if get
throws an ExecutionException
with an
Exception
as its causeExecutionError
- if get
throws an ExecutionException
with an Error
as its causeCancellationException
- if get
throws a CancellationException
Copyright © 2010–2019. All rights reserved.