Reputation: 183
In the code below, I added 2 FutureCallbacks to a single ListenableFuture.
And my question is: will the 2 FutureCallbacks be executed by the order I add them, or will they run separately and asynchronously?
The JavaDoc said, Registers separate success and failure callbacks to be run when the Future's computation is complete or, if the computation is already complete, immediately. 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.
I tried to add Thread.sleep(1000)
to one of the FutureCallbacks, then I found it blocks the other one, which confused me.
And I've also tried the addListener method, it runs asynchronously, that's for sure.
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
final ListenableFuture<String> future = service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "hello";
}
});
Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println(result+ " world");
}
@Override
public void onFailure(Throwable t) {
}
});
Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println(result+ " me");
}
@Override
public void onFailure(Throwable t) {
}
});
Upvotes: 0
Views: 3557
Reputation: 279960
will the 2
FutureCallback
s be executed by the order I add them, or will they run separately and asynchronously
First, it's important to note that Callback
instances and listeners registered after a Future
has completed trigger immediately.
The javadoc states
Note: If the callback is slow or heavyweight, consider supplying an executor. If you do not supply an executor,
addCallback
will use a direct executor, which carries some caveats for heavier operations. For example, the callback may run on an unpredictable or undesirable thread:
- If the input Future is done at the time
addCallback
is called,addCallback
will execute the callback inline.- If the input Future is not yet done,
addCallback
will schedule the callback to be run by the thread that completes the input Future, which may be an internal system thread such as an RPC network thread.Also note that, regardless of which thread executes the callback, all other registered but unexecuted listeners are prevented from running during its execution, even if those listeners are to run in other executors.
You can control if they are run separately by providing separate Executor
s when adding them (or the same but pooled). If you don't, the behavior is unpredictable, as the javadoc states.
(This is from a more recent version of Guava, but I think it applies to older versions as well.)
Upvotes: 1