think async in java 8

Post on 19-Jan-2017

1.542 Views

Category:

Software

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Think Asyncin Java 8

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

Casablanca | November 1-3, 2016 | @DevoxxMA

Dmitry Alexandrov

2

Principal expert developer in T-System10 years in Java enterpriseBulgarian JUG co-leadConference co-org@bercut2000dmitry.aleksandrov@t-systems.com

Plan for today: rethink the way we use system resources

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

Casablanca | November 1-3, 2016 | @DevoxxMA

Let’s try to understand the word:

Asynchronous

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

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

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

Asynchronous• … by why?

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

Casablanca | November 1-3, 2016 | @DevoxxMA

That class…• To get to the right understanding

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

But first: Evolution of

multithreading in Java

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

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

And with it came the…Future

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

Casablanca | November 1-3, 2016 | @DevoxxMA

Future – a primitive for creating multithreaded

applications

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

Casablanca | November 1-3, 2016 | @DevoxxMA

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

a function:getASpecialInt()

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

We have to put this work (in a container)

Future

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

Putting work in a containerPromise

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

Promise• A function to put a work in a

“container”

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

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

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

FutureFuture:

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

container

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

Conceptually we should NOT remove value outside of the container

Future

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

Future in Java

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

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

FutureThe interface was really simplistic:

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

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

FutureThe interface was really simplistic:

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

Are blocking..

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

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

Future

Submit()

get()

Result ready

main Thread 1

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

Future

Submit()

get()

Result ready

main Thread 1

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

Future

Submit()

get()

Result ready

main Thread 1

Do something Useful here

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

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

block

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

We have to make callbacks

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

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

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

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

they did it elsewhere?• JavaScript/Node.js

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

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

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

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

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

they did it elsewhere?

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

they did it elsewhere?

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

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

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

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

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

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

But not only in Javascript • Guava ListenableFuture addressed

the same issue

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

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

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

Guava

Futures.transform()…

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

Let’s now put it all together!

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

How to achieve asynchronicity in Java 8

*without additional libraries

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

It’s done by:CompletableFuture<T>

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

CompletableFuture<T>• Core library since Java 8

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

CompletableFuture<T><<Interface>>

Future<T>

CompletableFuture<?>

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

CompletableFuture<T><<Interface>>

Future<T>

<<Interface>>

CompletionStage<T>

CompletableFuture<?>

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

CompletableFuture<T><<Interface>>

Future<T>

<<Interface>>

CompletionStage<T>

CompletableFuture<?>

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

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

Foundation

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

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

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

Thread 1

QueueTask1

Task2

Task3

Task8

Task9

Processor

Thread 2

Queue

Processor

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

Thread 1

Queue

Processor

Thread 2

Queue

ProcessorTask1

Task2

Task3

Task8

Task9

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

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

Back to the CompletableFuture

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

Methods: create

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

Methods: create

• CompletableFuture() cf =new

CompletableFuture();

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

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

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

Methods: terminal

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

Methods: completeUnlike the Future<?>:

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

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

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

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

Methods: transform

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

Remember this?

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

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

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

Lets dive deeper

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

Composition

CF<T> CF<U>

Casablanca | November 1-3, 2016 | @DevoxxMA

Transform smart

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

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

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

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

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

Combine/Reduce

Step

Next step

Step

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

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

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

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

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

Combine/ReduceOr we want just the first available result:

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

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

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

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

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

Multiple futures• CompletableFuture<Void>

allOf(CompletableFuture<?>... cfs)

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

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

Multiple futures• CompletableFuture<Void>

allOf(CompletableFuture<?>... cfs)

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

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

Exceptions

Handle Exception

IOException

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

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

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

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);

The API• You have probably noticed

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

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

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

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

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

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

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

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

We have some (not so) bad heredity…

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

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

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

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

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

!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

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

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

REACTIVE

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

REACTIVE is the new CLOUD

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

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

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

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

new

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

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

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

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

And of course…

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

Reactive

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

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

Looks really nice• All benefits of async execution!

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

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

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

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

That’s all folks!

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

Any questions?

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

Thank you!Merci beaucoup!

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

top related