{"id":39,"date":"2019-11-04T20:09:57","date_gmt":"2019-11-04T14:39:57","guid":{"rendered":"https:\/\/pramodbiligirisblog.wordpress.com\/?p=39"},"modified":"2019-11-04T20:09:57","modified_gmt":"2019-11-04T14:39:57","slug":"how-is-google-guava-listenablefuture-better-than-java-future","status":"publish","type":"post","link":"https:\/\/www.pramodb.com\/index.php\/2019\/11\/04\/how-is-google-guava-listenablefuture-better-than-java-future\/","title":{"rendered":"How is Google Guava ListenableFuture better than Java Future?"},"content":{"rendered":"\n<p> <a href=\"https:\/\/github.com\/google\/guava\">Google Guava<\/a>\u2019s concurrency classes provide some advantages over using Java\u2019s default classes. Guava\u2019s Futures offer the following benefits:<\/p>\n\n\n<ol><li>You can add \u201clisteners\u201d to the result of a Future\u2019s success or failure, instead of explicitly checking for the return of the Future.get(), handling exceptions and so on<\/li><li>You can chain multiple asynchronous pieces of code together using provided utility functions rather than writing repetitive code for the same.<\/li><\/ol>\n\n\n<p>Below, we will see how to use the chaining feature. In the process, we will learn how  \u201clisteners\u201d are used internally to implement the same. <\/p>\n\n\n<p>What the code does is first create a UserId object, and then use it to obtain a UserDetails object. Both these operations are presumed to be long running operations in the real world, and hence implemented using Futures. I have added inline comments so hopefully it is all self-explanatory!<\/p>\n\n\n<pre class=\"wp-block-code\"><code>public class ListenableFutureExample1 {\n    public static void main(String&#091;] args) throws Exception {\n        \/\/ Step 1. Create an instance of an executor that provides instances of ListenableFuture-s\n        final ListeningExecutorService executor =\n                MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));\n        \/\/ Step 2. Use that to create a Future that returns a userId object\n        ListenableFuture&lt;UserId&gt; userIdFuture = executor.submit(\n            new Callable&lt;UserId&gt;() {\n                public UserId call() {\n                   \/\/ Initializing \"1\" as the user id\n                    return new UserId(1);\n                }\n            }\n        );\n        \/\/ Step 3. Let's say you want to convert the userId to userDetails.\n        \/\/ And for that you have  a function that may run for a long time and hence is better invoked\n        \/\/ asynchronously. Guava's AsyncFunction class is appropriate here\n        AsyncFunction&lt;UserId, UserDetails&gt; userDetails = new AsyncFunction&lt;UserId, UserDetails&gt;() {\n            public ListenableFuture&lt;UserDetails&gt; apply(UserId userId) {\n                return Futures.immediateFuture(new UserDetails(userId));\n                \/\/ The above instantiation of new UserDetails can be replaced with any long running\n                \/\/ piece of code\n            }\n        };\n        \/\/ Step 4. Chain the future and the function\n        \/\/ This works by registering a listener to the output of userIdFuture. This listener invokes the\n        \/\/ long running, asynchronous userDetails function above within the passed in executor\n        ListenableFuture&lt;UserDetails&gt; userDetailsFuture = Futures.transformAsync(userIdFuture,\n                userDetails, executor);\n        \/\/ Step 5. print the output (\"some username\")\n        System.out.println(userDetailsFuture.get().getUserName());\n        executor.shutdownNow();\n    }\n   \/\/ A simple holder of userId info\n    private static class UserId {\n        private long id;\n        public UserId(long id) {\n            this.id = id;\n        }\n    }\n   \/\/ Maps userId to username (currently a dummy implementation)\n    private static class UserDetails {\n        private final UserId userId;\n        public UserDetails(UserId userId) {\n            this.userId = userId;\n        }\n        public String getUserName() {\n            \/\/ This can be replaced by a lookup from userId to username\n            return \"some username\";\n        }\n    }\n}<\/code><\/pre>\n\n\n<p>Within the Guava library, the following piece of code in AbstractTransformFuture registers the AsyncFunction above as a listener to the userId Future object:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>    AsyncTransformFuture&lt;I, O&gt; output = new AsyncTransformFuture&lt;&gt;(input, function);\n    input.addListener(output, rejectionPropagatingExecutor(executor, output));<\/code><\/pre>\n\n\n<p>In the code above, &#8220;input&#8221; is the userId Future, and &#8220;function&#8221; is the passed in AsyncFunction.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Google Guava\u2019s concurrency classes provide some advantages over using Java\u2019s default classes. Guava\u2019s Futures offer the following benefits: You can add \u201clisteners\u201d to the result of a Future\u2019s success or failure, instead of explicitly checking for the return of the Future.get(), handling exceptions and so on You can chain multiple asynchronous pieces of code together [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[1],"tags":[9,15],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/posts\/39"}],"collection":[{"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/comments?post=39"}],"version-history":[{"count":0,"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/posts\/39\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/media?parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/categories?post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pramodb.com\/index.php\/wp-json\/wp\/v2\/tags?post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}