SlideShare a Scribd company logo
@JosePaumard
asynchronous
Java
CompletableFuture
Asynchronous?
@JosePaumard#Devoxx #J8Async
Asynchronous
Suppose we have three tasks to execute
T1
T2
T3
@JosePaumard#Devoxx #J8Async
Asynchronous
1st easy way to execute them:
« synchronous execution »
@JosePaumard#Devoxx #J8Async
Asynchronous
2nd way to do it:
« multithreaded execution »
@JosePaumard#Devoxx #J8Async
Asynchronous
2nd way to do it:
« multithreaded execution » … on only one core
@JosePaumard#Devoxx #J8Async
Asynchronous
3rd way to do it:
« asynchronous »
@JosePaumard#Devoxx #J8Async
Asynchronous
3rd way to do it:
« asynchronous » … even on a multicore
@JosePaumard#Devoxx #J8Async
Asynchronous
Synchronous vs asynchronous:
Is asynchronous any faster?
@JosePaumard#Devoxx #J8Async
Synchronous vs asynchronous:
Is asynchronous any faster?
Well it can be
Because it is « non blocking »
Asynchronous
@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
@JosePaumard#Devoxx #J8Async
Pattern
Asynchronous
queryEngine.select("select user from User")
.forEach(user -> System.out.prinln(user)) ;
@JosePaumard#Devoxx #J8Async
Pattern
Callback or task: lambda expression
Asynchronous
queryEngine.select("select user from User")
.forEach(user -> System.out.prinln(user)) ;
@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)) ;
@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)) ;
@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
@JosePaumard#Devoxx #J8Async
A task in Java
Pattern
Callable<String> task = () -> "select user from User" ;
Future<String> future = executorService.submit(task) ;
@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) ;
@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) ;
@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
@JosePaumard
@JosePaumard
@JosePaumard#Devoxx #J8Async
Questions?
#J8Async
@JosePaumard#Devoxx #J8Async
Creation of an asynchronous task
Let us see an example first
@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();
}
}
@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);
});
}
}
@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
@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
@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);
});
}
}
@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
@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);
});
}
}
@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);
@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);
@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
@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);
});
}
}
@JosePaumard#Devoxx #J8Async
How to test it?
This pattern:
executor.submit(() -> {
String result = longOperation();
asyncResponse.resume(result);
});
@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);
@JosePaumard#Devoxx #J8Async
How to test it?
But the nice thing is:
CompletableFuture<Void> completableFuture =
CompletableFuture.runAsync(() -> {
String result = longOperation();
asyncResponse.resume(result);
}, executor);
@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);
}
);
@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
@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();
@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
@JosePaumard#Devoxx #J8Async
What is a CompletableFuture?
A class that implements both Future and CompletionStage
@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
@JosePaumard#Devoxx #J8Async
Methods from Future
Five methods:
boolean cancel(boolean mayInterruptIfRunning) ;
@JosePaumard#Devoxx #J8Async
Methods from Future
Five methods:
boolean cancel(boolean mayInterruptIfRunning) ;
boolean isCanceled() ;
boolean isDone() ;
@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 ;
@JosePaumard#Devoxx #J8Async
More from CompletableFuture
Future-like methods:
V join() ; // may throw an unchecked exception
V getNow(V valueIfAbsent) ; // returns immediately
@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
@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
@JosePaumard#Devoxx #J8Async
How to create a CompletableFuture?
A completed CompletableFuture
public static <U> CompletableFuture<U> completedFuture(U value) ;
@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) ;
@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
@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
@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)
@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!
@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!
@JosePaumard#Devoxx #J8Async
CompletionStage – patterns
Some 1 – 1 patterns
public <U> CompletionStage<U>
thenApply(Function<? super T,? extends U> fn);
@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);
@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);
@JosePaumard#Devoxx #J8Async
CompletionStage – patterns
Some 2 – 1 patterns
public <U, V> CompletionStage<V> thenCombineAsync
(CompletionStage<U> other,
BiFunction<T, U, V> function) ;
@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) ;
@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) ;
@JosePaumard#Devoxx #J8Async
CompletionStage – patterns
Some more 2 – 1 patterns
public <U> CompletionStage<U> applyToEither
(CompletionStage<? extends T> other,
Function<T, U> function) ;
@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) ;
@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) ;
@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);
@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);
}
@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
@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);
@JosePaumard#Devoxx #J8Async
A second example
Async analysis of a web page
CompletableFuture.supplyAsync(
() -> readPage("http://whatever.com/")
)
@JosePaumard#Devoxx #J8Async
A second example
Async analysis of a web page
CompletableFuture.supplyAsync(
() -> readPage("http://whatever.com/")
)
.thenApply(page -> linkParser.getLinks(page))
@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!
) ;
@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
) ;
@JosePaumard#Devoxx #J8Async
A second example
Async analysis of a web page
public interface Executor {
void execute(Runnable command);
}
@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) ;
@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)
) ;
@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
) ;
@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
}
@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 */) ;
}
@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
}
@JosePaumard#Devoxx #J8Async
A last example
Async events in CDI
@Inject
Event<String> event ;
Executor executor = SwingUtilities::invokeLater
event.fireAsync("some event", executor) ;
@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
@JosePaumard#Devoxx #J8Async
CompletionStage – last patterns
Static methods
public static CompletableFuture<Void>
allOf(CompletableFuture<?>... cfs) ;
public static CompletableFuture<Object>
anyOf(CompletableFuture<?>... cfs) ;
@JosePaumard#Devoxx #J8Async
Exception handling
So, a CompletableFuture can depend on:
1) one CompletableFuture
2) two CompletableFuture
3) N CompletableFuture
@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?
@JosePaumard#Devoxx #J8Async
Exception handling
Suppose we have this CF pipeline
CF1 CF21
CF22
CF31
CF32
CF41
@JosePaumard#Devoxx #J8Async
Exception handling
Suppose we have this CF pipeline
And CF21 raises an exception
CF1 CF21
CF22
CF31
CF32
CF41
@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
@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
@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
@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
@JosePaumard#Devoxx #J8Async
Exception handling
Suppose CF30 has been created with exceptionnaly()
CF1 CF21
CF22
CF31
CF32
CF41
exceptionnaly()
CF30
@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
@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
@JosePaumard#Devoxx #J8Async
Exception handling
There are three methods to handle an exception
CompletionStage<T> exceptionally(
Function<Throwable, ? extends T> function);
@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);
@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);
@JosePaumard#Devoxx #J8Async
A very last example
CompletableFuture<String> closing = new CompletableFuture<String>() ;
Stream<String> manyStrings = Stream.of("one", "two", "three") ;
@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(""); })
@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)
@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)
@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
);
@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
);
@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();
@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();
@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();
@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();
}
@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();
@JosePaumard#Devoxx #J8Async
Conclusion
We have an API for async computations in the JDK!
@JosePaumard#Devoxx #J8Async
Conclusion
We have an API for async computations in the JDK!
Very rich, many methods which makes it complex
@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
@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
@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
@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
Thank you
Q/A

More Related Content

PDF
From Java 11 to 17 and beyond.pdf
PPTX
Spring boot Introduction
PPTX
Soap vs rest
PPTX
Introduction to Node js
PPTX
Rest api with node js and express
PPTX
Introduction to ASP.Net Viewstate
PDF
Deep Dive Java 17 Devoxx UK
PPSX
Spring - Part 1 - IoC, Di and Beans
From Java 11 to 17 and beyond.pdf
Spring boot Introduction
Soap vs rest
Introduction to Node js
Rest api with node js and express
Introduction to ASP.Net Viewstate
Deep Dive Java 17 Devoxx UK
Spring - Part 1 - IoC, Di and Beans

What's hot (20)

PPTX
Testing Spring Boot application in post-JUnit 4 world
PPT
Asynchronous JavaScript & XML (AJAX)
PDF
OAuth2 and Spring Security
PDF
JavaScript - Chapter 7 - Advanced Functions
PPTX
Rest assured
ODP
Angular 4 The new Http Client Module
ODP
Datatype in JavaScript
PDF
Ksug2015 - JPA3, JPA 내부구조
PDF
Hibernate Presentation
PDF
Introduction to Redux
PPTX
Express JS
PDF
Corso Javascript
PDF
Basics of JavaScript
PDF
Hexagonal architecture - message-oriented software design
PDF
Asynchronous javascript
PDF
TypeScript: coding JavaScript without the pain
PDF
The JavaScript Programming Language
PPTX
Advance Java Topics (J2EE)
PDF
Grokking TechTalk #33: High Concurrency Architecture at TIKI
PDF
JavaScript - Chapter 13 - Browser Object Model(BOM)
Testing Spring Boot application in post-JUnit 4 world
Asynchronous JavaScript & XML (AJAX)
OAuth2 and Spring Security
JavaScript - Chapter 7 - Advanced Functions
Rest assured
Angular 4 The new Http Client Module
Datatype in JavaScript
Ksug2015 - JPA3, JPA 내부구조
Hibernate Presentation
Introduction to Redux
Express JS
Corso Javascript
Basics of JavaScript
Hexagonal architecture - message-oriented software design
Asynchronous javascript
TypeScript: coding JavaScript without the pain
The JavaScript Programming Language
Advance Java Topics (J2EE)
Grokking TechTalk #33: High Concurrency Architecture at TIKI
JavaScript - Chapter 13 - Browser Object Model(BOM)
Ad

Viewers also liked (18)

PDF
The Future of Futures - A Talk About Java 8 CompletableFutures
PPTX
jDays - Spring Boot under the Hood
PDF
Completable future
PDF
Reactive Jersey Client
ODP
CompletableFuture
PPTX
Data Science for Retail Broking
PDF
First appeal under RTI Act 2005 against Registrar (J-I) Supreme Court of Indi...
PPTX
NET-A-PORTER AMP Hackathon
PDF
Transformation structurelle et émergence au Sénégal - Madaniou DIEME
PDF
Lost art of troubleshooting
PDF
Going reactive in java
PDF
DevOpsDays Baltimore March 2017 - Continuous Integration: A bittersweet love ...
PDF
Advanced Docker Developer Workflows on MacOS X and Windows
PPT
Environmental policy
PDF
Java 8, Streams & Collectors, patterns, performances and parallelization
PDF
Monitoring Kafka w/ Prometheus
PPTX
Containerd - core container runtime component
PDF
[Aurora事例祭り]AWS Database Migration Service と Schema Conversion Tool の使いドコロ
The Future of Futures - A Talk About Java 8 CompletableFutures
jDays - Spring Boot under the Hood
Completable future
Reactive Jersey Client
CompletableFuture
Data Science for Retail Broking
First appeal under RTI Act 2005 against Registrar (J-I) Supreme Court of Indi...
NET-A-PORTER AMP Hackathon
Transformation structurelle et émergence au Sénégal - Madaniou DIEME
Lost art of troubleshooting
Going reactive in java
DevOpsDays Baltimore March 2017 - Continuous Integration: A bittersweet love ...
Advanced Docker Developer Workflows on MacOS X and Windows
Environmental policy
Java 8, Streams & Collectors, patterns, performances and parallelization
Monitoring Kafka w/ Prometheus
Containerd - core container runtime component
[Aurora事例祭り]AWS Database Migration Service と Schema Conversion Tool の使いドコロ
Ad

Similar to Asynchronous API in Java8, how to use CompletableFuture (20)

PDF
Java concurrency model - The Future Task
PDF
Session 9 Android Web Services - Part 2.pdf
PDF
Leveraging Completable Futures to handle your query results Asynchrhonously
PPT
Node.js: CAMTA Presentation
PDF
Leverage CompletableFutures to handle async queries. DevNexus 2022
PPTX
동기화 시대를 뛰어넘는 비동기 프로그래밍
PDF
Build Web Apps using Node.js
PDF
How To Use IO Monads in Scala?
PPT
Asynchronous in dot net4
PDF
Java 8 Puzzlers as it was presented at Codemash 2017
PDF
Writing a REST Interconnection Library in Swift
PDF
Java APIs- The missing manual (concurrency)
PDF
Having Fun with Play
PPTX
Ultimate Node.js countdown: the coolest Application Express examples
PDF
JAX-RS 2.1 Reloaded @ Devoxx
PDF
The Mayans Lost Guide to RxJava on Android
PPTX
Ddd melbourne 2011 C# async ctp
PPTX
모던자바의 역습
PPTX
Mobile Application Development class 008
PDF
Concurrency and Thread-Safe Data Processing in Background Tasks
Java concurrency model - The Future Task
Session 9 Android Web Services - Part 2.pdf
Leveraging Completable Futures to handle your query results Asynchrhonously
Node.js: CAMTA Presentation
Leverage CompletableFutures to handle async queries. DevNexus 2022
동기화 시대를 뛰어넘는 비동기 프로그래밍
Build Web Apps using Node.js
How To Use IO Monads in Scala?
Asynchronous in dot net4
Java 8 Puzzlers as it was presented at Codemash 2017
Writing a REST Interconnection Library in Swift
Java APIs- The missing manual (concurrency)
Having Fun with Play
Ultimate Node.js countdown: the coolest Application Express examples
JAX-RS 2.1 Reloaded @ Devoxx
The Mayans Lost Guide to RxJava on Android
Ddd melbourne 2011 C# async ctp
모던자바의 역습
Mobile Application Development class 008
Concurrency and Thread-Safe Data Processing in Background Tasks

More from José Paumard (20)

PDF
Loom Virtual Threads in the JDK 19
PDF
The Future of Java: Records, Sealed Classes and Pattern Matching
PDF
Designing functional and fluent API: application to some GoF patterns
PDF
The Sincerest Form of Flattery
PPTX
The Sincerest Form of Flattery
PDF
Designing functional and fluent API: example of the Visitor Pattern
PDF
Construire son JDK en 10 étapes
PDF
Java Keeps Throttling Up!
PDF
Lambdas and Streams Master Class Part 2
PDF
Lambda and Stream Master class - part 1
PDF
Asynchronous Systems with Fn Flow
PDF
Java Full Throttle
PDF
JAX-RS and CDI Bike the (Reactive) Bridge
PDF
Collectors in the Wild
PDF
Streams in the wild
PDF
JAX RS and CDI bike the reactive bridge
PDF
Free your lambdas
PDF
L'API Collector dans tous ses états
PDF
Linked to ArrayList: the full story
PDF
Free your lambdas
Loom Virtual Threads in the JDK 19
The Future of Java: Records, Sealed Classes and Pattern Matching
Designing functional and fluent API: application to some GoF patterns
The Sincerest Form of Flattery
The Sincerest Form of Flattery
Designing functional and fluent API: example of the Visitor Pattern
Construire son JDK en 10 étapes
Java Keeps Throttling Up!
Lambdas and Streams Master Class Part 2
Lambda and Stream Master class - part 1
Asynchronous Systems with Fn Flow
Java Full Throttle
JAX-RS and CDI Bike the (Reactive) Bridge
Collectors in the Wild
Streams in the wild
JAX RS and CDI bike the reactive bridge
Free your lambdas
L'API Collector dans tous ses états
Linked to ArrayList: the full story
Free your lambdas

Recently uploaded (20)

PPTX
PPH.pptx obstetrics and gynecology in nursing
PPTX
Renaissance Architecture: A Journey from Faith to Humanism
PDF
O5-L3 Freight Transport Ops (International) V1.pdf
PPTX
Institutional Correction lecture only . . .
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PDF
Abdominal Access Techniques with Prof. Dr. R K Mishra
PDF
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
PDF
Origin of periodic table-Mendeleev’s Periodic-Modern Periodic table
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
PDF
01-Introduction-to-Information-Management.pdf
PDF
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PPTX
Cell Structure & Organelles in detailed.
PDF
Business Ethics Teaching Materials for college
PDF
VCE English Exam - Section C Student Revision Booklet
PDF
RMMM.pdf make it easy to upload and study
PPTX
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
PDF
Classroom Observation Tools for Teachers
PDF
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
PDF
Supply Chain Operations Speaking Notes -ICLT Program
PPH.pptx obstetrics and gynecology in nursing
Renaissance Architecture: A Journey from Faith to Humanism
O5-L3 Freight Transport Ops (International) V1.pdf
Institutional Correction lecture only . . .
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
Abdominal Access Techniques with Prof. Dr. R K Mishra
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
Origin of periodic table-Mendeleev’s Periodic-Modern Periodic table
STATICS OF THE RIGID BODIES Hibbelers.pdf
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
01-Introduction-to-Information-Management.pdf
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
Cell Structure & Organelles in detailed.
Business Ethics Teaching Materials for college
VCE English Exam - Section C Student Revision Booklet
RMMM.pdf make it easy to upload and study
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
Classroom Observation Tools for Teachers
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
Supply Chain Operations Speaking Notes -ICLT Program

Asynchronous API in Java8, how to use CompletableFuture

  • 3. @JosePaumard#Devoxx #J8Async Asynchronous Suppose we have three tasks to execute T1 T2 T3
  • 4. @JosePaumard#Devoxx #J8Async Asynchronous 1st easy way to execute them: « synchronous execution »
  • 5. @JosePaumard#Devoxx #J8Async Asynchronous 2nd way to do it: « multithreaded execution »
  • 6. @JosePaumard#Devoxx #J8Async Asynchronous 2nd way to do it: « multithreaded execution » … on only one core
  • 8. @JosePaumard#Devoxx #J8Async Asynchronous 3rd way to do it: « asynchronous » … even on a multicore
  • 9. @JosePaumard#Devoxx #J8Async Asynchronous Synchronous vs asynchronous: Is asynchronous any faster?
  • 10. @JosePaumard#Devoxx #J8Async Synchronous vs asynchronous: Is asynchronous any faster? Well it can be Because it is « non blocking » Asynchronous
  • 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. @JosePaumard#Devoxx #J8Async Pattern Asynchronous queryEngine.select("select user from User") .forEach(user -> System.out.prinln(user)) ;
  • 13. @JosePaumard#Devoxx #J8Async Pattern Callback or task: lambda expression Asynchronous queryEngine.select("select user from User") .forEach(user -> System.out.prinln(user)) ;
  • 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. @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. @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. @JosePaumard#Devoxx #J8Async A task in Java Pattern Callable<String> task = () -> "select user from User" ; Future<String> future = executorService.submit(task) ;
  • 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. @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. @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
  • 24. @JosePaumard#Devoxx #J8Async Creation of an asynchronous task Let us see an example first
  • 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. @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. @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. @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. @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. @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. @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. @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. @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. @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. @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. @JosePaumard#Devoxx #J8Async How to test it? This pattern: executor.submit(() -> { String result = longOperation(); asyncResponse.resume(result); });
  • 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. @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. @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. @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. @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. @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. @JosePaumard#Devoxx #J8Async What is a CompletableFuture? A class that implements both Future and CompletionStage
  • 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. @JosePaumard#Devoxx #J8Async Methods from Future Five methods: boolean cancel(boolean mayInterruptIfRunning) ;
  • 46. @JosePaumard#Devoxx #J8Async Methods from Future Five methods: boolean cancel(boolean mayInterruptIfRunning) ; boolean isCanceled() ; boolean isDone() ;
  • 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. @JosePaumard#Devoxx #J8Async More from CompletableFuture Future-like methods: V join() ; // may throw an unchecked exception V getNow(V valueIfAbsent) ; // returns immediately
  • 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. @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. @JosePaumard#Devoxx #J8Async How to create a CompletableFuture? A completed CompletableFuture public static <U> CompletableFuture<U> completedFuture(U value) ;
  • 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. @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. @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. @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. @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. @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. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 1 – 1 patterns public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
  • 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. @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. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some 2 – 1 patterns public <U, V> CompletionStage<V> thenCombineAsync (CompletionStage<U> other, BiFunction<T, U, V> function) ;
  • 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. @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. @JosePaumard#Devoxx #J8Async CompletionStage – patterns Some more 2 – 1 patterns public <U> CompletionStage<U> applyToEither (CompletionStage<? extends T> other, Function<T, U> function) ;
  • 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. @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. @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. @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. @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. @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. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page CompletableFuture.supplyAsync( () -> readPage("http://whatever.com/") )
  • 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. @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. @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. @JosePaumard#Devoxx #J8Async A second example Async analysis of a web page public interface Executor { void execute(Runnable command); }
  • 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. @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. @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. @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. @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. @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. @JosePaumard#Devoxx #J8Async A last example Async events in CDI @Inject Event<String> event ; Executor executor = SwingUtilities::invokeLater event.fireAsync("some event", executor) ;
  • 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. @JosePaumard#Devoxx #J8Async CompletionStage – last patterns Static methods public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) ; public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) ;
  • 85. @JosePaumard#Devoxx #J8Async Exception handling So, a CompletableFuture can depend on: 1) one CompletableFuture 2) two CompletableFuture 3) N CompletableFuture
  • 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. @JosePaumard#Devoxx #J8Async Exception handling Suppose we have this CF pipeline CF1 CF21 CF22 CF31 CF32 CF41
  • 88. @JosePaumard#Devoxx #J8Async Exception handling Suppose we have this CF pipeline And CF21 raises an exception CF1 CF21 CF22 CF31 CF32 CF41
  • 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. @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. @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. @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. @JosePaumard#Devoxx #J8Async Exception handling Suppose CF30 has been created with exceptionnaly() CF1 CF21 CF22 CF31 CF32 CF41 exceptionnaly() CF30
  • 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. @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. @JosePaumard#Devoxx #J8Async Exception handling There are three methods to handle an exception CompletionStage<T> exceptionally( Function<Throwable, ? extends T> function);
  • 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. @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. @JosePaumard#Devoxx #J8Async A very last example CompletableFuture<String> closing = new CompletableFuture<String>() ; Stream<String> manyStrings = Stream.of("one", "two", "three") ;
  • 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. @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. @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. @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. @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. @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. @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. @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. @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. @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. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK!
  • 111. @JosePaumard#Devoxx #J8Async Conclusion We have an API for async computations in the JDK! Very rich, many methods which makes it complex
  • 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. @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. @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. @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
  • 117. Q/A