Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Asynchronous API in Java8, how to use CompletableFuture

23.138 visualizaciones

Publicado el

Slides of my talk as Devoxx 2015. How to set up asynchronous data processing pipelines using the CompletionStage / CompletableFuture API, including how to control threads and how to handle exceptions.

Publicado en: Educación
  • DOWNLOAD FULL BOOKS, INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... 1.DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... 1.DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... 1.DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... 1.DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... 1.DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... 1.DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí

Asynchronous API in Java8, how to use CompletableFuture

  1. 1. @JosePaumard asynchronous Java CompletableFuture
  2. 2. Asynchronous?
  3. 3. @JosePaumard#Devoxx #J8Async Asynchronous Suppose we have three tasks to execute T1 T2 T3
  4. 4. @JosePaumard#Devoxx #J8Async Asynchronous 1st easy way to execute them: « synchronous execution »
  5. 5. @JosePaumard#Devoxx #J8Async Asynchronous 2nd way to do it: « multithreaded execution »
  6. 6. @JosePaumard#Devoxx #J8Async Asynchronous 2nd way to do it: « multithreaded execution » … on only one core
  7. 7. @JosePaumard#Devoxx #J8Async Asynchronous 3rd way to do it: « asynchronous »
  8. 8. @JosePaumard#Devoxx #J8Async Asynchronous 3rd way to do it: « asynchronous » … even on a multicore
  9. 9. @JosePaumard#Devoxx #J8Async Asynchronous Synchronous vs asynchronous: Is asynchronous any faster?
  10. 10. @JosePaumard#Devoxx #J8Async Synchronous vs asynchronous: Is asynchronous any faster? Well it can be Because it is « non blocking » Asynchronous
  11. 11. @JosePaumard#Devoxx #J8Async Difference with the synchronous multithreaded model? 1) The async engine decides to switch from one context to another 2) Single threaded = no issue with atomicity or visibility Performances? No multithreaded « context switch » Asynchronous
  12. 12. @JosePaumard#Devoxx #J8Async Pattern Asynchronous queryEngine.select("select user from User") .forEach(user -> System.out.prinln(user)) ;
  13. 13. @JosePaumard#Devoxx #J8Async Pattern Callback or task: lambda expression Asynchronous queryEngine.select("select user from User") .forEach(user -> System.out.prinln(user)) ;
  14. 14. @JosePaumard#Devoxx #J8Async Pattern Callback or task: lambda expression When the result is available, then we can continue with the next task Asynchronous queryEngine.select("select user from User") .forEach(user -> System.out.prinln(user)) ;
  15. 15. @JosePaumard#Devoxx #J8Async Pattern Callback or task: lambda expression When the result is available, then we can continue with the next task Now how can we write that in Java? Asynchronous queryEngine.select("select user from User") .forEach(user -> System.out.prinln(user)) ;
  16. 16. @JosePaumard#Devoxx #J8Async A task in Java Since Java 1: Runnable Since Java 5: Callable In Java 5 we have the ExecutorService (pool of threads) We give a task and get back a Future
  17. 17. @JosePaumard#Devoxx #J8Async A task in Java Pattern Callable<String> task = () -> "select user from User" ; Future<String> future = executorService.submit(task) ;
  18. 18. @JosePaumard#Devoxx #J8Async A task in Java Pattern Callable<String> task = () -> "select user from User" ; Future<String> future = executorService.submit(task) ; List<User> users = future.get() ; // blocking users.forEach(System.out::println) ;
  19. 19. @JosePaumard#Devoxx #J8Async A task in Java Pattern Passing an object from one task to another has to be handled in the « master » thread Callable<String> task = () -> "select user from User" ; Future<String> future = executorService.submit(task) ; List<User> users = future.get() ; // blocking users.forEach(System.out::println) ;
  20. 20. @JosePaumard#Devoxx #J8Async Asynchronous programming We have new tools in Java 8 to handle this precise case It brings new solutions to chain tasks And can handle both asynchronous and multithreaded programming
  21. 21. @JosePaumard
  22. 22. @JosePaumard
  23. 23. @JosePaumard#Devoxx #J8Async Questions? #J8Async
  24. 24. @JosePaumard#Devoxx #J8Async Creation of an asynchronous task Let us see an example first
  25. 25. @JosePaumard#Devoxx #J8Async Creation of an asynchronous task The Jersey way to create an asynchronous call @Path("/resource") public class AsyncResource { @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { new Thread(new Runnable() { public void run() { String result = longOperation(); asyncResponse.resume(result); } }).start(); } }
  26. 26. @JosePaumard#Devoxx #J8Async Creation of an asynchronous task (let us fix this code, this is Java 8) @Path("/resource") public class AsyncResource { @Inject private Executor executor; @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { executor.execute(() -> { String result = longOperation(); asyncResponse.resume(result); }); } }
  27. 27. @JosePaumard#Devoxx #J8Async How to test it? The question is: how can we test that code? We want to check if the result object is passed to the resume() method of the asyncResponse
  28. 28. @JosePaumard#Devoxx #J8Async How to test it? We have mocks for that! It is a very basic test, but tricky to write since we are in an asynchronous world
  29. 29. @JosePaumard#Devoxx #J8Async How to test it? Let us give one more look at the code @Path("/resource") public class AsyncResource { @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { executor.execute(() -> { // executed in the main thread String result = longOperation(); // executed in another thread asyncResponse.resume(result); }); } }
  30. 30. @JosePaumard#Devoxx #J8Async How to test it? We have mocks to check if resume() is properly called with result It is a very basic test, but tricky to write since we are in an asynchronous world
  31. 31. @JosePaumard#Devoxx #J8Async How to test it? We can inject a mock AsyncResponse, even mock the result @Path("/resource") public class AsyncResource { @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { executor.execute(() -> { String result = longOperation(); asyncResponse.resume(result); }); } }
  32. 32. @JosePaumard#Devoxx #J8Async How to test it? We can inject a mock AsyncResponse, even mock the result Then verify the correct interaction: But: - we need to verify this once the run() method has been called Mockito.verify(mockAsyncResponse).resume(result);
  33. 33. @JosePaumard#Devoxx #J8Async How to test it? We can inject a mock AsyncResponse, even mock the result Then verify the correct interaction: But: - we need to verify this once the run() method has been called - and take into account the multithreaded aspect… the read / writes on the mock should be « visible »! Mockito.verify(mockAsyncResponse).resume(result);
  34. 34. @JosePaumard#Devoxx #J8Async How to test it? So our constraints are the following: - we need to verify this once the run() method has been called - we need to read / write on our mocks in the same thread as the one which runs the task we want to test
  35. 35. @JosePaumard#Devoxx #J8Async How to test it? This is where CompletionStage comes to the rescue! @Path("/resource") public class AsyncResource { @Inject ExecutorService executor; @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { executor.submit(() -> { String result = longOperation(); asyncResponse.resume(result); }); } }
  36. 36. @JosePaumard#Devoxx #J8Async How to test it? This pattern: executor.submit(() -> { String result = longOperation(); asyncResponse.resume(result); });
  37. 37. @JosePaumard#Devoxx #J8Async How to test it? This pattern: Becomes this one: And does basically the same thing executor.submit(() -> { String result = longOperation(); asyncResponse.resume(result); }); CompletableFuture.runAsync(() -> { String result = longOperation(); asyncResponse.resume(result); }, executor);
  38. 38. @JosePaumard#Devoxx #J8Async How to test it? But the nice thing is: CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> { String result = longOperation(); asyncResponse.resume(result); }, executor);
  39. 39. @JosePaumard#Devoxx #J8Async How to test it? But the nice thing is: And on this object we can call: CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> { String result = longOperation(); asyncResponse.resume(result); }, executor); completableFuture .thenRun(() -> { Mockito.verify(mockAsyncResponse).resume(result); } );
  40. 40. @JosePaumard#Devoxx #J8Async How to test it? Be careful of visibility issues 1) It’s simpler to run everything in the same thread 2) Create, train and check our mocks in this thread
  41. 41. @JosePaumard#Devoxx #J8Async CompletionStage / CompletableFuture Two elements in this API: - an interface: CompletionStage - an implementing class: CompletableFuture The interface depends on CompletableFuture: public CompletableFuture<T> toCompletableFuture();
  42. 42. @JosePaumard#Devoxx #J8Async What is a CompletionStage? A model for a task: - that performs an action an may return a value when another completion stage completes - that may trigger other tasks So a completion stage is an element of a chain
  43. 43. @JosePaumard#Devoxx #J8Async What is a CompletableFuture? A class that implements both Future and CompletionStage
  44. 44. @JosePaumard#Devoxx #J8Async What is a CompletableFuture? A class that implements both Future and CompletionStage It has a state: - the task may be running - the task may have complete normally - the task may have complete exceptionnaly
  45. 45. @JosePaumard#Devoxx #J8Async Methods from Future Five methods: boolean cancel(boolean mayInterruptIfRunning) ;
  46. 46. @JosePaumard#Devoxx #J8Async Methods from Future Five methods: boolean cancel(boolean mayInterruptIfRunning) ; boolean isCanceled() ; boolean isDone() ;
  47. 47. @JosePaumard#Devoxx #J8Async Methods from Future Five methods: boolean cancel(boolean mayInterruptIfRunning) ; boolean isCanceled() ; boolean isDone() ; V get() ; // blocking call V get(long timeout, TimeUnit timeUnit) ; // may throw a checked exception throws InterruptedException, ExecutionException, TimeoutException ;
  48. 48. @JosePaumard#Devoxx #J8Async More from CompletableFuture Future-like methods: V join() ; // may throw an unchecked exception V getNow(V valueIfAbsent) ; // returns immediately
  49. 49. @JosePaumard#Devoxx #J8Async More from CompletableFuture Future-like methods: V join() ; // may throw an unchecked exception V getNow(V valueIfAbsent) ; // returns immediately boolean complete(V value) ; // sets the returned value is not returned void obtrudeValue(V value) ; // resets the returned value
  50. 50. @JosePaumard#Devoxx #J8Async More from CompletableFuture Future-like methods: V join() ; // may throw an unchecked exception V getNow(V valueIfAbsent) ; // returns immediately boolean complete(V value) ; // sets the returned value is not returned void obtrudeValue(V value) ; // resets the returned value boolean completeExceptionnaly(Throwable t) ; // sets an exception void obtrudeException(Throwable t) ; // resets with an exception
  51. 51. @JosePaumard#Devoxx #J8Async How to create a CompletableFuture? A completed CompletableFuture public static <U> CompletableFuture<U> completedFuture(U value) ;
  52. 52. @JosePaumard#Devoxx #J8Async How to create a CompletableFuture? A CompletableFuture from a Runnable or a Supplier public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) ; public static <U> CompletableFuture<U> supplyAsync(Supplier<U> value, Executor executor) ;
  53. 53. @JosePaumard#Devoxx #J8Async Building CompletionStage chains A CompletionStage is a step in a chain - it can be triggered by a previous CompletionStage - it can trigger another CompletionStage - it can be executed in a given Executor
  54. 54. @JosePaumard#Devoxx #J8Async Building CompletionStage chains What is a task? - it can be a Function - it can be a Consumer - it can be a Runnable
  55. 55. @JosePaumard#Devoxx #J8Async Building CompletionStage chains What kind of operation does it support? - chaining (1 – 1) - composing (1 – 1) - combining, waiting for both result (2 – 1) - combining, triggered on the first available result (2 – 1)
  56. 56. @JosePaumard#Devoxx #J8Async Building CompletionStage chains What kind of operation does it support? - chaining (1 – 1) - composing (1 – 1) - combining, waiting for both result (2 – 1) - combining, triggered on the first available result (2 – 1) All this gives… 36 methods!
  57. 57. @JosePaumard#Devoxx #J8Async Building CompletionStage chains In what thread can it be executed? - In the same executor as the caller - In a new executor, passed as a parameter - Asynchronously, ie in the common fork join pool All this gives… 36 methods!
  58. 58. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 1 – 1 patterns public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
  59. 59. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 1 – 1 patterns public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn); public CompletionStage<Void> thenRunAsync(Runnable action, Executor executor);
  60. 60. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 1 – 1 patterns public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn); public CompletionStage<Void> thenRunAsync(Runnable action, Executor executor); public CompletionStage<Void> thenComposeAsync( Function<? super T, ? extends CompletionStage<U>> fn);
  61. 61. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 2 – 1 patterns public <U, V> CompletionStage<V> thenCombineAsync (CompletionStage<U> other, BiFunction<T, U, V> function) ;
  62. 62. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 2 – 1 patterns public <U, V> CompletionStage<V> thenCombineAsync (CompletionStage<U> other, BiFunction<T, U, V> function) ; public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<U> other, BiConsumer<T, U> action) ;
  63. 63. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 2 – 1 patterns public <U, V> CompletionStage<V> thenCombineAsync (CompletionStage<U> other, BiFunction<T, U, V> function) ; public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<U> other, BiConsumer<T, U> action) ; public CompletionStage<Void> runAfterBothAsync (CompletionStage<?> other, Runnable action, Executor executor) ;
  64. 64. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some more 2 – 1 patterns public <U> CompletionStage<U> applyToEither (CompletionStage<? extends T> other, Function<T, U> function) ;
  65. 65. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some more 2 – 1 patterns public <U> CompletionStage<U> applyToEither (CompletionStage<? extends T> other, Function<T, U> function) ; public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? extends T> consumer) ;
  66. 66. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some more 2 – 1 patterns public <U> CompletionStage<U> applyToEither (CompletionStage<? extends T> other, Function<T, U> function) ; public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? extends T> consumer) ; public CompletionStage<Void> runAfterEitherAsync (CompletionStage<U> other, Runnable action, Executor executor) ;
  67. 67. @JosePaumard#Devoxx #J8Async Back to our first example So the complete pattern becomes this one 1) First we create our mocks String result = Mockito.mock(String.class); AsyncResponse response = Mockito.mock(AsyncResponse.class); Runnable train = () -> Mockito.doReturn(result).when(response).longOperation(); Runnable verify = () -> Mockito.verify(response).resume(result);
  68. 68. @JosePaumard#Devoxx #J8Async Back to our first example So the complete pattern becomes this one 2) Then we create the call & verify Runnable callAndVerify = () -> { asyncResource.executeAsync(response).thenRun(verify); }
  69. 69. @JosePaumard#Devoxx #J8Async Back to our first example So the complete pattern becomes this one 3) Then we create the task ExecutorService executor = Executors.newSingleThreadExecutor(); AsyncResource asyncResource = new AsyncResource(); asyncResource.setExecutorService(executor); CompletableFuture .runAsync(train, executor) // this trains our mocks .thenRun(callAndVerify); // this verifies our mocks
  70. 70. @JosePaumard#Devoxx #J8Async Back to our first example Since a CompletableFuture is also a Future, we can fail with a timeout if the test does not complete fast enough ExecutorService executor = Executors.newSingleThreadExecutor(); AsyncResource asyncResource = new AsyncResource(); asyncResource.setExecutorService(executor); CompletableFuture .runAsync(train, executor) // this trains our mocks .thenRun(callAndVerify) // this verifies our mocks .get(10, TimeUnit.SECONDS);
  71. 71. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") )
  72. 72. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") ) .thenApply(page -> linkParser.getLinks(page))
  73. 73. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") ) .thenApply(page -> linkParser.getLinks(page)) .thenAccept( links -> displayPanel.display(links) // in the right thread! ) ;
  74. 74. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") ) .thenApply(page -> linkParser.getLinks(page)) .thenAcceptAsync( links -> displayPanel.display(links), executor ) ;
  75. 75. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page public interface Executor { void execute(Runnable command); }
  76. 76. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page public interface Executor { void execute(Runnable command); } Executor executor = runnable -> SwingUtilities.invokeLater(runnable) ;
  77. 77. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") ) .thenApply(page -> linkParser.getLinks(page)) .thenAcceptAsync( links -> displayPanel.display(links), runnable -> SwingUtilities.invokeLater(runnable) ) ;
  78. 78. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") ) .thenApply(Parser::getLinks) .thenAcceptAsync( DisplayPanel::display, SwingUtilities::invokeLater ) ;
  79. 79. @JosePaumard#Devoxx #J8Async A last example Async events in CDI @Inject Event<String> event ; event.fire("some event") ; // returns void public void observes(@Observes String payload) { // handle the event, called in the firing thread }
  80. 80. @JosePaumard#Devoxx #J8Async A last example Async events in CDI public void observes(@Observes String payload) { // handle the event, called in the firing thread CompletableFuture.anyOf(/* some task */) ; }
  81. 81. @JosePaumard#Devoxx #J8Async A last example Async events in CDI @Inject Event<String> event ; event.fireAsync("some event") ; // returns CompletionStage<Object> public void observes(@ObservesAsync String payload) { // handle the event in another thread }
  82. 82. @JosePaumard#Devoxx #J8Async A last example Async events in CDI @Inject Event<String> event ; Executor executor = SwingUtilities::invokeLater event.fireAsync("some event", executor) ;
  83. 83. @JosePaumard#Devoxx #J8Async A last example Async events in CDI @Inject Event<String> event ; Executor executor = SwingUtilities::invokeLater CompletionStage<Object> cs = event.fireAsync("some event", executor) ; cs.whenComplete(...); // handle the exceptions
  84. 84. @JosePaumard#Devoxx #J8Async CompletionStage – last patterns Static methods public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) ; public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) ;
  85. 85. @JosePaumard#Devoxx #J8Async Exception handling So, a CompletableFuture can depend on: 1) one CompletableFuture 2) two CompletableFuture 3) N CompletableFuture
  86. 86. @JosePaumard#Devoxx #J8Async Exception handling So, a CompletableFuture can depend on: 1) one CompletableFuture 2) two CompletableFuture 3) N CompletableFuture What happens when an exception is thrown?
  87. 87. @JosePaumard#Devoxx #J8Async Exception handling Suppose we have this CF pipeline CF1 CF21 CF22 CF31 CF32 CF41
  88. 88. @JosePaumard#Devoxx #J8Async Exception handling Suppose we have this CF pipeline And CF21 raises an exception CF1 CF21 CF22 CF31 CF32 CF41
  89. 89. @JosePaumard#Devoxx #J8Async Exception handling Suppose we have this CF pipeline And CF21 raises an exception Then all the depending CF are in error CF1 CF21 CF22 CF31 CF32 CF41
  90. 90. @JosePaumard#Devoxx #J8Async Exception handling Which means that: - the call to isCompletedExceptionnaly() returns true - the call to get() throws an ExecutionException which cause is the root Exception
  91. 91. @JosePaumard#Devoxx #J8Async Exception handling Which means that: - the call to isCompletedExceptionnaly() returns true - the call to get() throws an ExecutionException which cause is the root Exception CompletableFuture can handle exceptions
  92. 92. @JosePaumard#Devoxx #J8Async Exception handling Suppose we have this CF pipeline And CF21 raises an exception Then all the depending CF are in error CF1 CF21 CF22 CF31 CF32 CF41
  93. 93. @JosePaumard#Devoxx #J8Async Exception handling Suppose CF30 has been created with exceptionnaly() CF1 CF21 CF22 CF31 CF32 CF41 exceptionnaly() CF30
  94. 94. @JosePaumard#Devoxx #J8Async Exception handling Suppose CF30 has been created with exceptionnaly() If CF21 completes normally, then CF30 just transmits the value CF1 CF21 CF22 CF31 CF32 CF41 exceptionnaly() CF30
  95. 95. @JosePaumard#Devoxx #J8Async Exception handling Suppose CF30 has been created with exceptionnaly() If CF21 completes normally, then CF30 just transmits the value If it raises an exception, then CF30 handles it and generate a value for CF31 CF1 CF21 CF22 CF31 CF32 CF41 exceptionnaly() CF30
  96. 96. @JosePaumard#Devoxx #J8Async Exception handling There are three methods to handle an exception CompletionStage<T> exceptionally( Function<Throwable, ? extends T> function);
  97. 97. @JosePaumard#Devoxx #J8Async Exception handling There are three methods to handle an exception handle() has also asynchronous versions CompletionStage<T> exceptionally( Function<Throwable, ? extends T> function); <U> CompletionStage<U> handle( BiFunction<? super T, Throwable, ? extends U> bifunction);
  98. 98. @JosePaumard#Devoxx #J8Async Exception handling There are three methods to handle an exception whenComplete() has also asynchronous versions CompletionStage<T> exceptionally( Function<Throwable, ? extends T> function); <U> CompletionStage<U> handle( BiFunction<? super T, Throwable, ? extends U> bifunction); CompletionStage<T> whenComplete( BiConsumer<? super T, Throwable> action);
  99. 99. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ;
  100. 100. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; manyStrings .onClose(() -> { closing.complete(""); })
  101. 101. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; manyStrings .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture)
  102. 102. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; manyStrings .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20)
  103. 103. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; manyStrings .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20) .reduce( closing, (cf1, cf2) -> cf1.thenCombine(cf2, binaryOperator) // concatenation );
  104. 104. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; CompletableFuture<String> reduce = manyStrings .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20) .reduce( closing, (cf1, cf2) -> cf1.thenCombine(cf2, binaryOperator) // concatenation );
  105. 105. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; CompletableFuture<String> reduce = manyStrings .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20) .reduce( closing, (cf1, cf2) -> cf1.thenCombine(cf2, binaryOperator) // concatenation ); manyStrings.close();
  106. 106. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; CompletableFuture<String> reduce = manyStrings .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20) .reduce( closing, (cf1, cf2) -> cf1.thenCombine(cf2, binaryOperator) // concatenation ); manyStrings.close();
  107. 107. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; CompletableFuture<String> reduce = manyStrings.parallel() .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20) .reduce( closing, (cf1, cf2) -> cf1.thenCombine(cf2, binaryOperator) // concatenation ); manyStrings.close();
  108. 108. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; Runnable sillyStreamComputation = () -> { CompletableFuture<String> reduce = manyStrings.parallel() .onClose(() -> { closing.complete(""); }) .map(CompletableFuture::completedFuture) .filter(cf -> cf.get().length() < 20) .reduce( closing, (cf1, cf2) -> cf1.thenCombine(cf2, binaryOperator) ); manyStrings.close(); }
  109. 109. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ; ForkJoinPool fj = new ForkJoinPool(4); CompetableFuture<String> criticalParallelComputation = CompletableFuture.runAsync(sillyStreamComputation, fj); someCriticalResult = criticalParallelComputation.get();
  110. 110. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK!
  111. 111. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK! Very rich, many methods which makes it complex
  112. 112. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK! Very rich, many methods which makes it complex Built on lambdas
  113. 113. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK! Very rich, many methods which makes it complex Built on lambdas Gives a fine control over threads
  114. 114. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK! Very rich, many methods which makes it complex Built on lambdas Gives a fine control over threads Handle chaining, composition
  115. 115. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK! Very rich, many methods which makes it complex Built on lambdas Gives a fine control over threads Handle chaining, composition Very clean way of handling exceptions
  116. 116. Thank you
  117. 117. Q/A

×