Guava Futures Wait for Callback
Solution 1
If you just want to block until the callbacks for the N tasks you submit have all completed, you could create a CountDownLatch
with a count
of N. Then just call countDown()
on it when each callback completes (whether it succeeds or fails) and await()
it at the point you want to block.
Alternatively, you could do something like you did in your answer, but rather than using a ListenableFutureTask<Void>
and a no-op Runnable
, just use a SettableFuture<Void>
instead and call set(null)
on it on completion.
Solution 2
How about if you create another future for each callback and make sure that it will be completed inside the callback.
// create "callback" future here
futures.add(callbackFuture);
Futures.addCallback(future, new FutureCallback<Object>() {
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
// do something with callbackFuture
}
@Override
public void onSuccess(Object x) {
try {Thread.sleep((Integer) x * 10);} catch (Exception e) {}
System.out.println(x);
// do something with callbackFuture
}
});
vinoths
Updated on June 25, 2022Comments
-
vinoths almost 2 years
I have a list of futures and on completion of each future, I have a callback that should get executed.
I am using Futures.successfulAsList to check if all the futures have completed. However, this doesn't take into account the completion of callback.
Is there a way I can ensure the callback is completed?
Instead of Callback, I could use Futures.transform to wrap into another Future and check for completion of that. However, with this, I don't get access to runtime exception thrown in the wrapped future.
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(20)); List<ListenableFuture<Object>> futures = new ArrayList<>(); for (int i = 1; i <= 20; i++) { final int x = i * 100; ListenableFuture<Object> future = service.submit(new Callable() { @Override public Object call() throws Exception { Thread.sleep(10000 / x); return x; } }); futures.add(future); Futures.addCallback(future, new FutureCallback<Object>() { @Override public void onFailure(Throwable t) { t.printStackTrace(); } @Override public void onSuccess(Object x) { try {Thread.sleep((Integer) x * 10);} catch (Exception e) {} System.out.println(x); } }); } ListenableFuture<List<Object>> listFuture = Futures .successfulAsList(futures); System.out.println("Waiting..."); System.out.println(listFuture.get()); System.out.println("Done");