Over a million developers have joined DZone.

Google Guava Concurrency – ListenableFuture

· Java Zone

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

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

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}