Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Completable future

666 views

Published on

Completable future . Presented at Java Users Group Bangalore

Published in: Software
  • Be the first to comment

Completable future

  1. 1. Completable Future Srinivasan Raghavan Senior Member of Technical Staff Java Platform Group Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
  2. 2. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Program Agenda java.util.Future Introduction Cloud Services Design and the fight for Performance CompletableFuture and power of parallelism Building powerful libraries with Completable Future 1 2 3 4 4
  3. 3. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | java.util.Future Introduction • Before jdk1.5 , no java.util.concurrent.*, only threads ,synchronized primitives • W ite o e , u a ywhe e ? – g eat su ess , But u it a illio ti es , wo k the sa e ? ig uestio • In came java.util.concurrent.* with executor service and future tasks and many other concurrency constructs • A java.util.Future is a construct which holds a result available at a later time • Future is asynchronous , but its not non-blocking 5
  4. 4. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | The Executor Service and Future Task • Executors contains pool of threads which accepts tasks and supplies to the Future • When a task is submitted to the executor it returns a future and future.get() would block the computation until it ends 6 ExecutorService executorService = Executors.newFixedThreadPool(20); Future<Integer> future = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return 42; } }); System.out.println(future.get()); executorService.shutdown(); User Executor Task (Callable) Future
  5. 5. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | What can be done ? • Future can allow computation in the background so improving performance • Future.get() would block the thread and wait till the computation is complete and get the result • Can get an exception if there is a failure • future.cancel() cancels the computation • future.isDone() checks the computation is complete • A d that’s it ///// 7 ExecutorService executorService = Executors.newFixedThreadPool(20); Future<Integer> future = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { //Some complex work return 42; } }); System.out.println(future.get()); executorService.shutdown();
  6. 6. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Distributed Cloud Services Design and the fight for Performance 8
  7. 7. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | A Typical distributed cloud service 9 Get data from service provider 1 Get data from service provider 3 Get data from service provider 2 Combine Data Response(result) Request(userData,reuestParams) Processing for analytics Process data for the user Generate recommendation
  8. 8. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Performance Bottlenecks and impacts • Java.util.Future can help in parallelism • But it cannot help with pipeline the tasks and managing the thread pool for you • Future does not supports call backs and chaining of operations • Building libraries with future can be complictaed • Performing in a serial way can impact the latency big time • It can destroy all benefits of having distributed services • No amount of horizontal and vertical scaling can help • Without dynamic services offerings business can be affected 10
  9. 9. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | CompletableFuture and power of parallelism 11
  10. 10. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | What is Completable future ? • Its new addition to java 8 • Asynchronous, allows registering asyc callbacks just like java scripts, event-driven programming model • Support for depending functions to be triggered on completion • Each stage can be executed with different executor pool • Also comes with a built in thread pool for executing tasks • Built in lambda support ,super flexible and scalable api 12
  11. 11. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Basics 13 CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { // ...long running... return "42"; } }, executor1); future.get(); //Come on ... we are in JDK 8 !!! CompletableFuture<String> future = CompletableFuture .supplyAsync(() -> "42",executor1); future.get();
  12. 12. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Lambdas , Crash Recap 14
  13. 13. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Lambdas • Function definition that is not bound to an identifier 15 /** * * This is a piece of code that illustrate how lambdas work in Java 8 * * Given an example * * f(x) = 2x+5; * * given x= 2 ; f(x) = 9 ; * * z(x)= f(g(x)) where g(x) =3x+5 * * z(x) = 2(3x+5) +5 = 6x+15 12+15 = 27 * * */ public class LambdaUnderStanding2 { @FunctionalInterface static interface Funct { int apply(int x); default Funct compose(Funct before) { return (x) -> apply(before.apply(x)); } } public static void main(String[] args) { Funct annoymous = new Funct() { @Override public int apply(int x) { return 2 * x + 5;; } }; Funct funct = (x) -> 2 * x + 5; System.out.println(funct.apply(2)); Funct composed = funct.compose((x) -> 3 * x + 5); System.out.println(composed.apply(2)); } }
  14. 14. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Java 8 Functional Interface 16 Predicate<Integer> test = (x) -> x> 10; Function<Integer, Integer> function = (x) -> 3 * x + 5; Consumer<Integer> print = (x) -> System.out.println(x); BiFunction<Integer, Integer, Integer> biFunction = (x, y) -> 3 * x + 4* y + 2; Supplier<Integer> supplier = () -> Integer.MAX_VALUE;
  15. 15. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | thenApply() -transformations 17 /** * Classic call back present in javascript or scala . * theApply is like run this function when the result *arrives from previous stages */ final CompletableFuture<Integer> future1 = CompletableFuture .supplyAsync(() -> "42", executor1).thenApply( (x) -> Integer.parseInt(x)); /** * thenApply is trasformative changing CompletableFuture<Integer> to * CompletableFuture<Double> */ CompletableFuture<Double> future2 = CompletableFuture .supplyAsync(() -> "42", executor1) .thenApply((x) -> Integer.parseInt(x)) .thenApply(r -> r * r * Math.PI); /** * U can supply a differnt executor pool for thenApply */ CompletableFuture<Double> future = CompletableFuture .supplyAsync(() -> "42", executor1) .thenApplyAsync((x) -> Integer.parseInt(x), executor2) .thenApplyAsync(r -> r * r * Math.PI, executor2);
  16. 16. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | thenCombine() , whenComplete() –completion 18 final CompletableFuture<Integer> future = CompletableFuture .supplyAsync(() -> "32", executor1).thenApply( (x) -> Integer.parseInt(x)); CompletableFuture.supplyAsync(() -> "42", executor2) .thenApply((x) -> Integer.parseInt(x)) .thenCombine(future, (x, y) -> x + y) .thenAccept((result) -> System.out.println(result)); /** * When complete is final stage where it can check the execpetions * propagated and pass results through it */ final CompletableFuture<Integer> future = CompletableFuture .supplyAsync(() -> "42", executor1) .thenApply((x) -> Integer.parseInt(x)) .whenComplete( (x, throwable) -> { if (throwable != null) { Logger.getAnonymousLogger().log(Level.SEVERE, "Logging" + throwable); } else { Logger.getAnonymousLogger().log(Level.FINE, " Passed " + x); } });
  17. 17. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | thenCombine() allOf() - combining futures 19 /** * Combining two dependent futures */ final CompletableFuture<Integer> future = CompletableFuture .supplyAsync(() -> "32", executor1).thenApply( (x) -> Integer.parseInt(x)); CompletableFuture.supplyAsync(() -> "42", executor2) .thenApply((x) -> Integer.parseInt(x)) .thenCombine(future, (x, y) -> x + y) .thenAccept((result) -> System.out.println(result)); /** * Combining n futures unrelated */ CompletableFuture<Void> future2 = CompletableFuture .supplyAsync(() -> "42", executor1) .thenApplyAsync((x) -> Integer.parseInt(x), executor2) .thenAcceptAsync( (x) -> Logger.getAnonymousLogger().log(Level.FINE, "Logging" + x), executor2); CompletableFuture<Void> future1 = CompletableFuture .supplyAsync(() -> “ ", executor1) .thenApplyAsync((x) -> Integer.parseInt(x), executor2) .thenAcceptAsync( (x) -> Logger.getAnonymousLogger().log(Level.FINE, "Logging" + x), executor2); CompletableFuture.allOf(future1,future2).join();
  18. 18. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Building powerful libraries with Completable Future 20
  19. 19. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Building powerful libraries with completable futures • Building scalable service orchestrator • Building dynamic http client framework • Improve parallelism in existing services with are done serial • Building libraries tuned for vertical scalability 21
  20. 20. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | References • https://docs.oracle.com/javase/tutorial/ • https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Completa bleFuture.html • http://cs.oswego.edu/mailman/listinfo/concurrency-interest • https://github.com/srinivasanraghavan/functional 22
  21. 21. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Questions ? 23

×