CompletableFuture

6,811 views
6,244 views

Published on

Published in: Technology, Business
0 Comments
16 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,811
On SlideShare
0
From Embeds
0
Number of Embeds
66
Actions
Shares
0
Downloads
102
Comments
0
Likes
16
Embeds 0
No embeds

No notes for slide

CompletableFuture

  1. 1. 初探 CompletableFuture @kojilin twjug 2013/9/7
  2. 2. Long running task ● Dependent Tasks Retrieving data from server Processing data Writing to storage Showing result to user
  3. 3. Blocking API executor.execute(() -> { UserDto dto = service.retrieveUser(); User user = accounts.processUser(dto); Storage.writeUser(user); }); ● Coarse-grained – Web service, DB, Process Data ● Control flow is verbose – if-else, try-catch-finally
  4. 4. executor.execute(() -> { try { UserDto dto = service.retrieveUser(); if(dto == null) return; User user = accounts.processDto(dto); Storage.writeUser(user); } catch(RemoteException e) { // alert user } finally { // ... }
  5. 5. Non-blocking API void Service#retrieveUser(callback); void Accounts#processUser(dto, callback); void Storage#writeUser(user, callback); ● When Task B depends on Task A ● A → B → C → D → E → …
  6. 6. Chaining async call step1(function (value1){ step2(value1, function(value2){ step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });
  7. 7. Non-blocking API Future<UserDto> Service#retrieveUser(); Future<User> Accounts#processUser(dto); Future<User> Storage#writeUser(user); ● No more callback hell
  8. 8. Chaining async call future = step1(); future.then(value1 -> {step2(value1)}) .then(value2 -> {step3(value2)}) .then(value3 -> {step4(value3)}) .onComplete(value4 -> { // Do something with value 4 });
  9. 9. jQuery // $.get returns a jqXHR(derived from a // Deferred object) var request = $.get(url); var chained = request.then( function(data) { return $.get(url2, {user:data.userId}); }); chained.done(function(data) { // ... });
  10. 10. Guava ListenableFuture<User> f1 = service.retrieveUserInfo(); ListenableFuture<User> f2 = Futures.transform(future1, (AsyncFunction<UserDto, User>) dto -> { return accounts.processDto(dto); }); ListenableFuture<User> f3 = Futures.transform(future2, (AsyncFunction<User, User>) user ->{ return storage.writeUser(user); });
  11. 11. Scala val f1 = future{ service.retrieveUserInfo() } val f2 = f1.map{ dto => accounts.processDto(dto) } val f3 = f2.map{ user=> storage.writeUser(user) } f3 onComplete{ case Success(_) => … case Failure(t) => println() }
  12. 12. What is Future? ● Future, promise, and delay – They describe an acts as a proxy for a result that is initially unknown, usually because the computation of its value is yet incomplete – They are often used Interchangeably ● Some differences in usage between future and promise – Future read – Promise write
  13. 13. Future API ● jQuery – Deferred Object – deferred.promise() ● Java – Future ● .Net Framework – Task – Async & Await keyword ● Scala – Future & Promise
  14. 14. Future ● java.util.concurrent.Future future = downloadSite(); // do something future.get(); future.get(3, TimeUnit.SECONDS); future.getNow();
  15. 15. Java SE 8
  16. 16. CompletableFuture
  17. 17. CompletableFuture ● Functional ● Monadic ● Asynchronous ● Event-driven
  18. 18. 下載和安裝 ● Downlaod from http://jdk8.java.net/lambda/ ● Unzip it !! ● 本投影片是基於b105
  19. 19. JavaDoc
  20. 20. @FunctionalInterface ● Supplier<T> – T get() ● Runnable – void run() ● Function<T, R> – R apply(T t) ● Consumer – void accept(T t)
  21. 21. @FunctionalInterface ● BiFunction<T, U, R> – R apply(T t, U u) ● BiConsumer<T, U> – void accept(T t, U u)
  22. 22. 類別宣告 public class CompletableFuture<T> implements Future<T>, CompletionStage<T> { // ... }
  23. 23. 使用方式 CompletableFuture<String> doSomeThing() { final CompletableFuture<String> future = new CompletableFuture<>(); // async call complete, // completeExceptionally, cancel return future; }
  24. 24. Write methods ● When two or more threads attempt to complete, completeExceptionally, or cancel a CompletableFuture, only one of them succeeds /* * @param mayInterruptIfRunning this value has no effect in * this implementation because interrupts are not used to * control processing. **/ public boolean cancel(boolean mayInterruptIfRunning)
  25. 25. 使用方式 CompletableFuture.supplyAsync(() -> { // long running job... return result; }); CompletableFuture.runAsync(() -> { // long running job });
  26. 26. 使用端等待結果 future = doSomeThing(); future.get(); future.get(3, TimeUnit.SECONDS); future.getNow();
  27. 27. 使用端使用 Callback future = doSomeThing(); future.whenComplete((result, throwable -> { if(throwable != null){ return; } //... do something with result });
  28. 28. Error handling future = downloadPage(); future.exceptionally(ex -> { return defaultContent; }); CompletableFuture<T> exceptionally( Function<Throwable,? extends T> fn)
  29. 29. whenComplete CompletableFuture<T> whenComplete( BiConsumer<? super T,? super Throwable> action) future = doSomeThing(); /** returns a new CompletionStage with * the same result or exception as this stage */ future2 = future.whenComplete((result, throwable -> { //... do something with result });
  30. 30. handle future = doSomeThing(); future.handle((result, throwable -> { //... do something with result return 12; }); CompletableFuture<U> handle( BiFunction<? Super T, Throwable , ? extends U> fn)
  31. 31. Transforming future = downloadPage(); future.thenApply(s -> { return s.size(); }); <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn)
  32. 32. Chaining future = downloadPage(); future.thenCompose(s -> { return parsePage(s); }); <U> CompletableFuture<U> thenCompose( Function<? super T, CompletableFuture<U>> fn)
  33. 33. After complete future = downloadPage(); future.thenRun(() -> { // ... }); CompletableFuture<Void> thenAccept( Consumer<? super T> block) CompletableFuture<Void> thenRun( Runnable action)
  34. 34. After Both CompletableFuture<Void> thenAcceptBoth( CompletableFuture<? extends U> other, BiConsumer<? super T, ? super U> action) CompletableFuture<Void> runAfterBoth( CompletableFuture<?> other, Runnable action)
  35. 35. Transform After Either future = downloadPage(site1); future.applyToEither(downloadPage(site2), S -> { // ... return result; }); CompletableFuture<Void> applyToEither( CompletableFuture<? extends T> other, Function<? super T, U> fn)
  36. 36. After Either CompletableFuture<Void> acceptEither( CompletableFuture<? extends T> other, Consumer<? super T> action) CompletableFuture<Void> runAfterEither( CompletableFuture<?> other, Runnable action)
  37. 37. Any 和 All static CompletableFuture<Void> all( CompletableFuture<?>... cfs) static CompletableFuture<Object> anyOf( CompletableFuture<?>... cfs)
  38. 38. API variation xXXX(XXX xxx) xXXXAsync(XXX xxx) xXXXAsync(XXX xxx, Executor executor)
  39. 39. API variation ● Without Async postfix – By the thread complete current future or any other caller of a completion method ● With Async postfix – Using ForkJoinPool.commonPool() ● With Async postfix and Executor param – Using Executor
  40. 40. 注意 ● 自己控制complete方法 future.thenAccept(r -> { // ... }); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); });
  41. 41. 注意 ● 自己控制complete方法 future.thenAccept(r -> { // ... }); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); }); 1 2
  42. 42. 注意 ● 自己控制complete方法 future.thenAcceptAsync(r -> { // ... }); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); });
  43. 43. 注意 ● 自己控制complete方法 future.thenAcceptAsync(r -> { // ... }, executor); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); });
  44. 44. 注意 ● 自己控制complete方法 future.thenAcceptAsync(r -> { // ... }, executor); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); }); newSingleThreadExecutor newCachedThreadPool
  45. 45. 參考資料 ● Java Concurrency in Practice ● The way of the Future, Futures in .NET, Java and JavaScript – http://blog.softmemes.com/2012/06/18/the-way-of-the-fu ● [concurrency-interest] Interface CompletionStage – http://cs.oswego.edu/pipermail/concurrency-interest/201
  46. 46. 參考資料 ● SIP-14 - Futures and Promises – http://docs.scala-lang.org/sips/pending/futures-promises ● Java 8: Definitive guide to CompletableFuture – http://nurkiewicz.blogspot.no/2013/05/java-8-definitive-g ● Java 8: CompletableFuture in action – http://nurkiewicz.blogspot.no/2013/05/java-8-completabl ● Futures and Promises in Scala 2.10 – https://speakerdeck.com/heathermiller/futures-and-prom

×