Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guava Futures Wait for Callback

Tags:

java

future

guava

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");
like image 535
vinoths Avatar asked Jul 16 '13 08:07

vinoths


People also ask

What is futures addCallBack?

addCallBack(): addCallback(ListenableFuture<V> future, FutureCallback<? super V> callback) Registers separate success and failure callbacks to be run when the Future's computation is complete or, if the computation is already complete, immediately.

What is ListenableFuture?

One lacking feature when using java. util. concurrent. Future is the ability to add listeners to run on completion, which is a common feature provided by most popular asynchronous frameworks.


1 Answers

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.

like image 80
ColinD Avatar answered Oct 04 '22 20:10

ColinD