• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
CompletableFuture
 

CompletableFuture

on

  • 2,585 views

 

Statistics

Views

Total Views
2,585
Views on SlideShare
2,568
Embed Views
17

Actions

Likes
7
Downloads
25
Comments
0

4 Embeds 17

https://twitter.com 12
http://www.linkedin.com 2
https://www.rebelmouse.com 2
https://www.linkedin.com 1

Accessibility

Upload Details

Uploaded via as OpenOffice

Usage Rights

CC Attribution-NonCommercial LicenseCC Attribution-NonCommercial License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    CompletableFuture CompletableFuture Presentation Transcript

    • 初探 CompletableFuture @kojilin twjug 2013/9/7
    • Long running task ● Dependent Tasks Retrieving data from server Processing data Writing to storage Showing result to user
    • 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
    • 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 { // ... }
    • 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 → …
    • Chaining async call step1(function (value1){ step2(value1, function(value2){ step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });
    • Non-blocking API Future<UserDto> Service#retrieveUser(); Future<User> Accounts#processUser(dto); Future<User> Storage#writeUser(user); ● No more callback hell
    • 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 });
    • 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) { // ... });
    • 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); });
    • 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() }
    • 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
    • Future API ● jQuery – Deferred Object – deferred.promise() ● Java – Future ● .Net Framework – Task – Async & Await keyword ● Scala – Future & Promise
    • Future ● java.util.concurrent.Future future = downloadSite(); // do something future.get(); future.get(3, TimeUnit.SECONDS); future.getNow();
    • Java SE 8
    • CompletableFuture
    • CompletableFuture ● Functional ● Monadic ● Asynchronous ● Event-driven
    • 下載和安裝 ● Downlaod from http://jdk8.java.net/lambda/ ● Unzip it !! ● 本投影片是基於b105
    • JavaDoc
    • @FunctionalInterface ● Supplier<T> – T get() ● Runnable – void run() ● Function<T, R> – R apply(T t) ● Consumer – void accept(T t)
    • @FunctionalInterface ● BiFunction<T, U, R> – R apply(T t, U u) ● BiConsumer<T, U> – void accept(T t, U u)
    • 類別宣告 public class CompletableFuture<T> implements Future<T>, CompletionStage<T> { // ... }
    • 使用方式 CompletableFuture<String> doSomeThing() { final CompletableFuture<String> future = new CompletableFuture<>(); // async call complete, // completeExceptionally, cancel return future; }
    • 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)
    • 使用方式 CompletableFuture.supplyAsync(() -> { // long running job... return result; }); CompletableFuture.runAsync(() -> { // long running job });
    • 使用端等待結果 future = doSomeThing(); future.get(); future.get(3, TimeUnit.SECONDS); future.getNow();
    • 使用端使用 Callback future = doSomeThing(); future.whenComplete((result, throwable -> { if(throwable != null){ return; } //... do something with result });
    • Error handling future = downloadPage(); future.exceptionally(ex -> { return defaultContent; }); CompletableFuture<T> exceptionally( Function<Throwable,? extends T> fn)
    • 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 });
    • handle future = doSomeThing(); future.handle((result, throwable -> { //... do something with result return 12; }); CompletableFuture<U> handle( BiFunction<? Super T, Throwable , ? extends U> fn)
    • Transforming future = downloadPage(); future.thenApply(s -> { return s.size(); }); <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn)
    • Chaining future = downloadPage(); future.thenCompose(s -> { return parsePage(s); }); <U> CompletableFuture<U> thenCompose( Function<? super T, CompletableFuture<U>> fn)
    • After complete future = downloadPage(); future.thenRun(() -> { // ... }); CompletableFuture<Void> thenAccept( Consumer<? super T> block) CompletableFuture<Void> thenRun( Runnable action)
    • After Both CompletableFuture<Void> thenAcceptBoth( CompletableFuture<? extends U> other, BiConsumer<? super T, ? super U> action) CompletableFuture<Void> runAfterBoth( CompletableFuture<?> other, Runnable action)
    • 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)
    • After Either CompletableFuture<Void> acceptEither( CompletableFuture<? extends T> other, Consumer<? super T> action) CompletableFuture<Void> runAfterEither( CompletableFuture<?> other, Runnable action)
    • Any 和 All static CompletableFuture<Void> all( CompletableFuture<?>... cfs) static CompletableFuture<Object> anyOf( CompletableFuture<?>... cfs)
    • API variation xXXX(XXX xxx) xXXXAsync(XXX xxx) xXXXAsync(XXX xxx, Executor executor)
    • 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
    • 注意 ● 自己控制complete方法 future.thenAccept(r -> { // ... }); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); });
    • 注意 ● 自己控制complete方法 future.thenAccept(r -> { // ... }); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); }); 1 2
    • 注意 ● 自己控制complete方法 future.thenAcceptAsync(r -> { // ... }); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); });
    • 注意 ● 自己控制complete方法 future.thenAcceptAsync(r -> { // ... }, executor); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); });
    • 注意 ● 自己控制complete方法 future.thenAcceptAsync(r -> { // ... }, executor); executor.execute(() -> { future.complete(result); // ... accounts.create(result.icon); }); newSingleThreadExecutor newCachedThreadPool
    • 參考資料 ● 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
    • 參考資料 ● 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