Core Java

Google Guava Concurrency – ListenableFuture

In my last post I covered using the Monitor class from the com.google.common.util.concurrent package in the Guava Library. In this post I am going to continue my coverage of Guava concurrency utilities and discuss the ListenableFuture interface. A ListenableFuture extends the Future interface from the java.util.concurrent package, by adding a method that accepts a completion listener.

ListenableFuture

a ListenableFuture behaves in exactly the same manner as a java.util.concurrent.Future but has the method addCallback(Runnable, ExecutorService) that executes the callback in the given executor. Here is an example:

 ListenableFuture futureTask = executorService.submit(callableTask)
 futureTask.addListener(new Runnable() {
            @Override
            public void run() {
               ..work after futureTask completed
            }
        }, executorService);

If the submitted task has completed when you add the callback, it will run immediately. Using the addCallback method has a drawback in that the Runnable does not have access to the result produced by the future. For access to the result of the Future you would need to use a FutureCallback.

FutureCallback

A FutureCallback accepts the results produced from the Future and specifies onSuccess and onFailure methods. Here is an example:

 class FutureCallbackImpl implements FutureCallback<String> {

        @Override
        public void onSuccess(String result){
             .. work with result
        }

        @Override
        public void onFailure(Throwable t) {
            ... handle exception
        }
    }

A FutureCallback is attached by using the addCallback method in the Futures class:

  Futures.addCallback(futureTask, futureCallbackImpl);

At this point you may be asking how do you get an instance of ListenableFuture, when an ExecutorService only returns Futures? The answer is to use the ListenableExecutionService.

ListenableExecutionService

To use a ListenableExecutionService simply decorate an ExecutorService instance with a call to MoreExecutors.listeningDecorator(ExecutorService) for example:

ExecutorsService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());

Conclusion

With the ability to add a callback, whether a Runnable or the FutureCallback that handles success and failure conditions, the ListenableFuture could be a valuable addition to your arsenal. I have created a unit-test demonstrating using the ListenableFuture available as a gist. In my next post I am going to cover the Futures class, which contains static methods for working with futures.

Resources

 
Reference: Google Guava Concurrency – ListenableFuture from our JCG partner Bill Bejeck at the Random Thoughts On Coding blog.

Bill Bejeck

Husband, father of 3, passionate about software development.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button