think async in java 8

144
Think Async in Java 8 dalexandrov.net | @bercut2000 | jug.bg | @bgjug Casablanca | November 1-3, 2016 | @DevoxxMA Dmitry Alexandrov

Upload: dmitry-alexandrov

Post on 19-Jan-2017

1.541 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Think Async in Java 8

Think Asyncin Java 8

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Dmitry Alexandrov

Page 2: Think Async in Java 8

2

Principal expert developer in T-System10 years in Java enterpriseBulgarian JUG co-leadConference [email protected]@t-systems.com

Page 3: Think Async in Java 8

Plan for today: rethink the way we use system resources

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 4: Think Async in Java 8

Let’s try to understand the word:

Asynchronous

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 5: Think Async in Java 8

Asynchronous• A form of computer control timing

protocol in which a specific operation begins after receiving a signal

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 6: Think Async in Java 8

Asynchronous• A form of computer control timing

protocol in which a specific operation begins after receiving a signal

• Not going at the same rate or exactly together with something else.

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 7: Think Async in Java 8

Asynchronous• In simple words:– Start the task somewhere else

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 8: Think Async in Java 8

Asynchronous• In simple words:– Start the task somewhere else– Notify me when its ready and I’ll process

the result

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 9: Think Async in Java 8

Asynchronous• In simple words:– Start the task somewhere else– Notify me when its ready and I’ll process

the result–… in terms of Java: start a new thread,

do something there, somehow get the result

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 10: Think Async in Java 8

Asynchronous• … by why?

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 11: Think Async in Java 8

Asynchronous• … by why?– It can be really faster

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 12: Think Async in Java 8

Asynchronous• … by why?– It can be really faster– Because its non-blocking

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 13: Think Async in Java 8

That class…• To get to the right understanding

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 14: Think Async in Java 8

That class…• To get to the right understanding• We need to have a look at it from

some different perspectives

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 15: Think Async in Java 8

That class…• To get to the right understanding• We need to have a look at it from

some different perspectives • Because several technologies

actually made it happen

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 16: Think Async in Java 8

But first: Evolution of

multithreading in Java

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 17: Think Async in Java 8

How it all began: Threads

public class HelloRunnable implements Runnable { public void run() { //get some value and store it a shared variable }

public static void main(String[] args) { (new Thread(new HelloRunnable())).start(); }}

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 18: Think Async in Java 8

How it all began: Threads

Or…

public class HelloThread extends Thread { public void run() { //get some value and store it a shared variable }

public static void main(String[] args) { (new HelloThread()).start(); }}

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 19: Think Async in Java 8

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 20: Think Async in Java 8

But then: Executor Services

And then Concurrency API has been introduced back in 2004 with the release of Java 5

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 21: Think Async in Java 8

But then: Executor Services

So that we no longer had to think at such a low level…

ExecutorService executorService = Executors.newFixedThreadPool(10);

executorService.execute(new Runnable() { public void run() { System.out.println("Asynchronous task"); }});

executorService.shutdown();

dalexandrov.net | @bercut2000 | jug.bg | @bgjugCasablanca | November 1-3, 2016 | @DevoxxMA

Page 22: Think Async in Java 8

And with it came the…Future

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 23: Think Async in Java 8

Future – a primitive for creating multithreaded

applications

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 24: Think Async in Java 8

Actually that’s not something too new:

A somewhat similar concept future was introduced in 1977 in a paper by Henry Baker and Carl Hewitt.

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 25: Think Async in Java 8

a function:getASpecialInt()

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 26: Think Async in Java 8

We have to put this work (in a container)

Future

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 27: Think Async in Java 8

Putting work in a containerPromise

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 28: Think Async in Java 8

Promise• A function to put a work in a

“container”

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 29: Think Async in Java 8

Promise• A function to put a work in a

“container”

• This is not something new too..

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 30: Think Async in Java 8

The term promise was proposed in 1976 by Daniel P. Friedman and David Wise,[1] and Peter

Hibbard called it eventual..

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 31: Think Async in Java 8

FutureFuture:

- observe container and make callbacks- transform resulting value inside the

container

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 32: Think Async in Java 8

Conceptually we should NOT remove value outside of the container

Future

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 33: Think Async in Java 8

Future in Java

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 34: Think Async in Java 8

FutureReally hided lots of the intrinsic of the multithreading

ExecutorService executor = Executors.newFixedThreadPool(1);Future<Integer> future = executor.submit(task);

System.out.println("future done? " + future.isDone());

Integer result = future.get();

System.out.println("future done? " + future.isDone());System.out.print("result: " + result);

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 35: Think Async in Java 8

FutureThe interface was really simplistic:

• isDone()• Get() • Get(..timeout)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 36: Think Async in Java 8

FutureThe interface was really simplistic:

• isDone()• Get() • Get(..timeout)

Are blocking..

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 37: Think Async in Java 8

FutureThe interface was really simplistic:

• isDone()• Get() • Get(..timeout)

So we are breaking the law!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 38: Think Async in Java 8

Future

Submit()

get()

Result ready

main Thread 1

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 39: Think Async in Java 8

Future

Submit()

get()

Result ready

main Thread 1

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 40: Think Async in Java 8

Future

Submit()

get()

Result ready

main Thread 1

Do something Useful here

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 41: Think Async in Java 8

From the definition:we don’t have to wait or

block

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 42: Think Async in Java 8

We have to make callbacks

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 43: Think Async in Java 8

CallbacksImagine:public static void processResultAsync(Supplier<List<Long>> supplier, ExecutorService executor, Consumer<List<Long>> onSuccess, Consumer<Throwable> onFail) { executor.submit(() -> { try { List<Long> lines = supplier.get(); onSuccess.accept(lines); } catch (Exception e) { onFail.accept(e); } });

}

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 44: Think Async in Java 8

CallbacksAnd now how we use it:final ExecutorService executor = Executors.newSingleThreadExecutor();

processResultAsync( AsyncCallbacks::getFibunacci, executor, System.out::println, Throwable::printStackTrace);

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 45: Think Async in Java 8

CallbacksBut the logic becomes really thick if get into callbacks:final ExecutorService executor = Executors.newSingleThreadExecutor();

processResultAsync( AsyncCallbacks::getPrime, executor, r -> processResultAsync( AsyncCallbacks::getFibunacci, executor, t-> System.out.println(r.stream() .filter(t::contains) .collect(Collectors.toList())), Throwable::printStackTrace ), Throwable::printStackTrace);

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 46: Think Async in Java 8

they did it elsewhere?• JavaScript/Node.js

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 47: Think Async in Java 8

they did it elsewhere?• JavaScript/Node.js• Non-blocking API, event driven model

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 48: Think Async in Java 8

they did it elsewhere?• JavaScript/Node.js• Non-blocking API, event driven model• Callbacks!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 49: Think Async in Java 8

they did it elsewhere?• JavaScript/Node.js• Non-blocking API, event driven model• Callbacks! That’s so cool!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 50: Think Async in Java 8

they did it elsewhere?• JavaScript/Node.js• Non-blocking API, event driven model• Callbacks! That’s so cool!• But in reality…

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 51: Think Async in Java 8

they did it elsewhere?

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 52: Think Async in Java 8

they did it elsewhere?

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 53: Think Async in Java 8

Say “callback” to a JavaScript developer and he will start

crying instantaneously!

Venkat Subramaniam

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 54: Think Async in Java 8

How they did it elsewhere

• JavaScript/Node.js• Non-blocking API, event driven model• Callbacks! That’s so cool!• But in reality… not cool!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 55: Think Async in Java 8

How they did it elsewhere

• JavaScript/Node.js• Non-blocking API, event driven model• Callbacks! That’s so cool!• But in reality… not cool!• But promises kinda fixed that.

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 56: Think Async in Java 8

How they did it elsewhere

So instead of:

step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); });});

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 57: Think Async in Java 8

How they did it elsewhere

This look oh so much better:

Q.fcall(promisedStep1) .then(promisedStep2) .then(promisedStep3) .then(promisedStep4) .then(function (value4) {

// Do something with value4 }) .catch(function (error) {

// Handle any error from all above steps }) .done();

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 58: Think Async in Java 8

But not only in Javascript • Guava ListenableFuture addressed

the same issue

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 59: Think Async in Java 8

But not only in Javascript • Guava ListenableFuture addressed

the same issue

• But it was complicated..

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 60: Think Async in Java 8

GuavaListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUMBER_OF_THREADS));

ListenableFuture<String> listenableFuture = executor.submit(asyncTask);

Futures.addCallback(listenableFuture, new FutureCallback<String>() { public void onSuccess(String result) { doMoreWithTheResultImmediately(result); }

public void onFailure(Throwable thrown) { handleFailure(thrown); }});

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 61: Think Async in Java 8

Guava

Futures.transform()…

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 62: Think Async in Java 8

Let’s now put it all together!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 63: Think Async in Java 8

How to achieve asynchronicity in Java 8

*without additional libraries

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 64: Think Async in Java 8

It’s done by:CompletableFuture<T>

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 65: Think Async in Java 8

CompletableFuture<T>• Core library since Java 8

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 66: Think Async in Java 8

CompletableFuture<T><<Interface>>

Future<T>

CompletableFuture<?>

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 67: Think Async in Java 8

CompletableFuture<T><<Interface>>

Future<T>

<<Interface>>

CompletionStage<T>

CompletableFuture<?>

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 68: Think Async in Java 8

CompletableFuture<T><<Interface>>

Future<T>

<<Interface>>

CompletionStage<T>

CompletableFuture<?>

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 69: Think Async in Java 8

CompletableFuture<T>• Core library since Java 8• Implements Future<T>• Implements CompletionStage<T>

– Composition element– Function resolution– Link through results– Transformation methods– toCompletableFuture()

• Async operations

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 70: Think Async in Java 8

Foundation

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 71: Think Async in Java 8

1. Lambdas & Method ref.

• No more explicit Callables or Runnables

• No more ugly anonymous classes

• Just use Lambdas and Method references

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 72: Think Async in Java 8

2. ForkJoinThe ForkJoinPool (since JDK7) is an ideal helper for async programs

• Cares for cache corruption• Knows better when and where a task should run• Optimized for tasks creating new tasks• Avoid changing threads until workload is significant

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Casablanca | November 1-3, 2016 | @DevoxxMA

Page 73: Think Async in Java 8

Thread 1

QueueTask1

Task2

Task3

Task8

Task9

Processor

Thread 2

Queue

Processor

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 74: Think Async in Java 8

Thread 1

Queue

Processor

Thread 2

Queue

ProcessorTask1

Task2

Task3

Task8

Task9

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 75: Think Async in Java 8

Thread 1

Queue

Processor

Thread 2

Queue

ProcessorTask1

Task2

Task3

Task8

Task9

Work stealing

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 76: Think Async in Java 8

Back to the CompletableFuture

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 77: Think Async in Java 8

Methods: create

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 78: Think Async in Java 8

Methods: create

• CompletableFuture() cf =new

CompletableFuture();

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 79: Think Async in Java 8

Methods: create

• CompletableFuture<U>::supplyAsync(Supplier<U> supplier)

• CompletableFuture<U>::runAsync(Runnable runnable)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 80: Think Async in Java 8

Methods: create• CompletableFuture<U>::supplyAsync(Supplier<U

> supplier[, Executor executor])

• CompletableFuture<U>::runAsync(Runnable runnable[, Executor executor])

• ForkJoin.commonPool() by default

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 81: Think Async in Java 8

Methods: terminal

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 82: Think Async in Java 8

Methods: completeUnlike the Future<?>:

• CompletableFuture()::– complete(T value)– completeExceptionally(Throwable e)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 83: Think Async in Java 8

Methods: terminal• Can be completed only once!

• Can be run async but does not exclude blocking!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 84: Think Async in Java 8

Methods: terminal• CompletableFuture<Void>::thenAccept(Consumer

<T> c)

• CompletableFuture<Void>::thenRun(Runnable action)

• Async versions

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 85: Think Async in Java 8

Methods: transform

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Remember this?

Page 86: Think Async in Java 8

Methods: transform• CompletableFuture<U>::thenApply(Function<T,U

> fn)– Done in the same thread

• CompletableFuture<U>::thenApplyAsync(Function<T,U> fn, [Executor executor])

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 87: Think Async in Java 8

So if we get back to asyncWe just get the Prime method as it is:

public static List<Long> getPrimes() { List<Long> found = new ArrayList<Long>(); …. return found;}

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 88: Think Async in Java 8

So if we get back to asyncAnd just write one single line:

CompletableFuture.supplyAsync(AsyncCallbacks::getPrime) .thenAccept(System.out::println);

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 89: Think Async in Java 8

Lets dive deeper

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 90: Think Async in Java 8

Composition

CF<T> CF<U>

Casablanca | November 1-3, 2016 | @DevoxxMA

Transform smart

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 91: Think Async in Java 8

CompositionBut if we want both Futures to be completed in sequence:

• CompletableFuture<U>:: thenCompose(Function<T,CompletableFuture<U>> fn)

• CompletableFuture<U>:: thenComposeAsync(Function<T,CompletableFuture<U>> fn)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 92: Think Async in Java 8

CompositionBut if we want both Futures to be completed in sequence :

• CompletableFuture<U>:: thenCompose(Function<T,CompletableFuture<U>> fn)

• CompletableFuture<U>:: thenComposeAsync(Function<T,CompletableFuture<U>> fn)

.. to avoid: CompletableFuture<CompletableFuture<T>>

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 93: Think Async in Java 8

CompositionBut if we want both Futures to be completed:

• CompletableFuture<U>:: thenCompose(Function<T,CompletableFuture<U>> fn)

• CompletableFuture<U>:: thenComposeAsync(Function<T,CompletableFuture<U>> fn)

.. to avoid: CompletableFuture<CompletableFuture<T>>

.. just like flatMap

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 94: Think Async in Java 8

And we getCompletableFuture<String> FilesUtils.readFileAsync(Path path)

CompletableFuture.supplyAsync(FilesUtils.readFileAsync(“…”)) .thenComposeAsync(content->processContent(content)) .thenAccept(System.out::println);

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 95: Think Async in Java 8

Combine/Reduce

Step

Next step

Step

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 96: Think Async in Java 8

CombinationSo if the previous step returns Future<T>:

• CompletableFuture<V>:: thenCombine(CompletionStage<U> other, BiFunction<T,U,V> fn)

• CompletableFuture<V>:: thenCombineAsync(CompletionStage<U> other, BiFunction<T,U,V> fn)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 97: Think Async in Java 8

Combination• Just imagine how that would be with just Futures:

Future<List<Integer>> primesFuture = getPrimes();Future<List<Integer>> fibunacciFuture = getFibunacci();

...List<Integer> primes = primesFuture.get();List<Integer> fibunaccis= fibunacciFuture.get();// intersect

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 98: Think Async in Java 8

Combine/ReduceAnd we don’t want further processing:

• CompletableFuture<Void>:: thenAcceptBoth(CompletableFuture<U> other, BiConsumer<T,U> block)

• CompletableFuture<Void>::runAfterBoth(CompletableFuture<?> other, Runnable action)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 99: Think Async in Java 8

Combine/ReduceOr we want just the first available result:

• CompletableFuture<Void>:: acceptEither(CompletableFuture<T> other, Consumer<T> block)

• CompletableFuture<Void>:: runAfterEither(CompletableFuture<?> other, Runnable action)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 100: Think Async in Java 8

Combine/ReduceOr we want just the first available result:

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 101: Think Async in Java 8

Combine/ReduceOr we want just the first available result:

• But what happens to the second one?

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 102: Think Async in Java 8

Combine/ReduceOr we want just the first available result:

• But what happens to the second one?

• So handle with care!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg |

@bgjug

Page 103: Think Async in Java 8

Combine/ReduceOr we want just the first available result:

• But what happens to the second one?

• So handle with care!

• getNumberOfDependents()Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg |

@bgjug

Page 104: Think Async in Java 8

Combine/Reduce• CompletableFuture<U>::

applyToEither(CompletableFuture<? extends T> other, Function<? super T,U> fn)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 105: Think Async in Java 8

Multiple futures• CompletableFuture<Void>

allOf(CompletableFuture<?>... cfs)

• CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 106: Think Async in Java 8

Multiple futures• CompletableFuture<Void>

allOf(CompletableFuture<?>... cfs)

• CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 107: Think Async in Java 8

Exceptions

Handle Exception

IOException

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 108: Think Async in Java 8

Exceptions• CompletableFuture<T>::exceptionally(Function<

Throwable,T> fn)

• CompletableFuture<Void>::handle(BiFunction<T,Throwable,U> fn)

• The exception is passed through the chainCasablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg |

@bgjug

Page 109: Think Async in Java 8

ExceptionsLooks really safe:

CompletableFuture<Integer> safe = future.handle((val, ex) -> { if (val != null) { return Long.valueOf(val); } else { log.warn("Huston, we a have problem!", ex); return -1; }});

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 110: Think Async in Java 8

Exceptions

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

CompletableFuture.supplyAsync(FilesUtils.readFileAsync(“…”)) .thenComposeAsync(content->processContent(content)) .thenAccept(System.out::println) .exceptionally(Throwable::printStackTrace);

Page 111: Think Async in Java 8

The API• You have probably noticed

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 112: Think Async in Java 8

The API• You have probably noticed • Unlike the Future<T>

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 113: Think Async in Java 8

The API• You have probably noticed • Unlike the Future<T>• The API is really BIG

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 114: Think Async in Java 8

The API• You have probably noticed • Unlike the Future<T>• The API is really BIG• Mostly fits the pattern:

<function>[Async](param,[Executer])

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 115: Think Async in Java 8

The API• You have probably noticed • Unlike the Future<T>• The API is really BIG• Mostly fits the pattern:

<function>[Async](param,[Executer])

Casablanca | November 1-3, 2016 | @DevoxxMA

>60 methods!!!

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 116: Think Async in Java 8

CF for async• Organize the work as a chain/flow of events/tasks– Do this then that (chaining)– Do this and/or that (joining)– Do this on failure (recovering)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 117: Think Async in Java 8

CF for async• When we program asynchronously we usually

think in terms of workflows, events and tasksQuery

“Primes”

Query “Fibs”

Gather perf data

Gather statistics

Return response

Log data

Handle Exception

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 118: Think Async in Java 8

We have some (not so) bad heredity…

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 119: Think Async in Java 8

Get• T get() throws InterruptedException, ExecutionException

• T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException

• T getNow(T valueIfAbcent)

• T join() throws CancellationException, CompletionException

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 120: Think Async in Java 8

Get• T get() throws InterruptedException, ExecutionException

• T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException

• T getNow(T valueIfAbcent)

• T join() throws CancellationException, CompletionException

• T obtrudeValue() never ever use that!!!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 121: Think Async in Java 8

So have in mind:Imagine:

@GET@Path("intersection")public String getIntersection() throws ExecutionException, InterruptedException { CompletableFuture<List<Long>> fib = new FibunacciFuture().getFibunacci(50L); CompletableFuture<List<Long>> primes = new PrimeFuture().getPrime(10000L); CompletableFuture<List<Long>> intersection = fib.thenCombineAsync(primes, (a, b) ->

a.stream() .filter(b::contains) .collect(Collectors.toList())); return intersection.thenApply(List::toString).get();}

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 122: Think Async in Java 8

So have in mind:Imagine:

@GET@Path("intersection")public String getIntersection() throws ExecutionException, InterruptedException { CompletableFuture<List<Long>> fib = new FibunacciFuture().getFibunacci(50L); CompletableFuture<List<Long>> primes = new PrimeFuture().getPrime(10000L); CompletableFuture<List<Long>> intersection = fib.thenCombineAsync(primes, (a, b) ->

a.stream() .filter(b::contains) .collect(Collectors.toList())); return intersection.thenApply(List::toString).get();}

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 123: Think Async in Java 8

!Get()

“Prime”

Result ready

main Thread 1 Thread 2

Result ready

“Fibunacci”

Result ready

GET

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 124: Think Async in Java 8

Should be supported all over

@GET@Path("intersectionAsync")public void getIntersectionAsync(@Suspended AsyncResponse response) { CompletableFuture<List<Long>> fib = new FibunacciFuture().getFibunacci(50L); CompletableFuture<List<Long>> primes = new PrimeFuture().getPrime(10000L); CompletableFuture<List<Long>> intersection = fib.thenCombineAsync(primes, (a, b) -> a.stream() .filter(b::contains) .collect(Collectors.toList()));

intersection.thenApplyAsync(List::toString).thenApplyAsync(response::resume).exceptionally(e->response.resume(e.getLocalizedMessage()));

response.setTimeout(10, TimeUnit.SECONDS); response.setTimeoutHandler(e->response.resume(new TimeoutException()));}

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 125: Think Async in Java 8

Async everywhere

Casablanca | November 1-3, 2016 | @DevoxxMA

“Prime”

Result ready

main Thread 1 Thread 2

Result ready

“Fibunacci”

Both results ready

GET

dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 126: Think Async in Java 8

REACTIVE

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 127: Think Async in Java 8

REACTIVE is the new CLOUD

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 128: Think Async in Java 8

If you program reactively:

• You are the master of the Universe• Your salary doubles every time you

say this word• You are the star of the Java geek

parties

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 129: Think Async in Java 8

If you program reactively:

• You are the master of the Universe• Your salary doubles every time you

say this word• You are the star of the Java geek

parties• … until serverless came out

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 130: Think Async in Java 8

But lets be honest• Actually, there is nothing so much

new

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 131: Think Async in Java 8

But lets be honest• Actually, there is nothing so much

new• Remember the Observable Pattern?

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 132: Think Async in Java 8

But lets be honest• Actually, there is nothing so much

new• Remember the Observable Pattern?• The key word is Asynchronous

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 133: Think Async in Java 8

But lets be honest• Actually, there is nothing so much

new• Remember the Observable Pattern?• The key word is Asynchronous• Java 8 supports now the pattern

really niceCasablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg |

@bgjug

Page 134: Think Async in Java 8

And of course…

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 135: Think Async in Java 8

Reactive

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 136: Think Async in Java 8

And what a good Reactive is

• Avoid blocking threads– Optimize the CPU usage

• Avoid changing threads– Optimize cache usage

• Avoid crippling failures– Failure of one task should be isolated and

handled elegantlyCasablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg |

@bgjug

Page 137: Think Async in Java 8

Looks really nice• All benefits of async execution!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 138: Think Async in Java 8

Looks really nice• All benefits of async execution!

• Fits well to the reactive pattern!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 139: Think Async in Java 8

Looks really nice• All benefits of async execution!

• Fits well to the reactive pattern!

• Comes out of the box!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 140: Think Async in Java 8

Looks really nice• All benefits of async execution!

• Fits well to the reactive pattern!

• Comes out of the box!

• Handle with care)

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 141: Think Async in Java 8

That’s all folks!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 142: Think Async in Java 8

Any questions?

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug

Page 143: Think Async in Java 8

Thank you!Merci beaucoup!

Casablanca | November 1-3, 2016 | @DevoxxMA dalexandrov.net | @bercut2000 | jug.bg | @bgjug