Understanding commodity futures Basis - Online Trading: Futures
The Future of Futures - A Talk About Java 8 CompletableFutures
-
Upload
haim-yadid -
Category
Software
-
view
1.691 -
download
3
description
Transcript of The Future of Futures - A Talk About Java 8 CompletableFutures
ilJUG Java 8 Launch Event The Future of Futures
(Apr 2014) !
Haim Yadid - Performize-IT
About Me: Haim Yadid
•21 Years of SW development experience •Performance Expert •Consulting R&D Groups •Training: Java Performance Optimization •Organizing : ILJUG
IL JUG
•Israeli Java User Group •Reborn at 1/14 •Meetup : http://www.meetup.com/IL-JUG •G+: https://plus.google.com/u/0/communities/110138558454900054301
•Twitter: @il_jug
The Beginning of Times
•Before J1.5 •Primitive life forms without Future •Threads •synchronization primitives •wait / notify •Most likely you will do it wrong
Futures Introduction
•j.u.c.Future •introduced in JDK 1.5 •jsr166 (Doug Lea) •Together with Executors •And many other concurrency constructs •Part of the java.util.concurrent
What is a Future
•A container for a result that will become available at a later time •Backed by a thread •May contain a Throwable if computation fails
What is a Future
•Future means asynchronous •Future does not mean non blocking •Future does not mean reactive
The ExecutorService
•Executor service is the container which handles a future •Has the threads which futures need. •Part of j.u.c (Executors.newXXX) •SingleThreadExecutor •FixedThreadPool •CachedThreadPool •ScheduledThreadPool
Simplest Example
ExecutorService e = Executors.newSingleThreadExecutor();! Future<Integer> future = e.submit( () -> {sleep(1000);return 42;} ) ; // do something useful ? System.out.println(future.get());
Lambda expression which represents a Callable<Integer>
User
Task(Callable, Runnable)
Future
Executor
What Else Can Be Done?
•So we are blocked until future is finished •If it throw exception get will throw an exception •More that can be done: !
!
!
•And thats all !
future.cancel(false) ; // cancel future if not executed yet (in queue) future.cancel(true); // in addition interrupt the running task future.isCancelled(); // wether the future is cancelled. future.idDone() // whether the future is done.
Futures Pros
•Futures combined with Callables are cheaper than threads. •Easier to maintain. •Async
We will get to the cons…
Futures Evolution -‐ Java 6
•Java 6 -jsr166x (CompletionService) •Separation of concerns
ExecutorService e = Executors.newFixedThreadPool(10);!CompletionService<Integer> completionService = new ExecutorCompletionService<>(e);! completionService.submit(() -> {sleep(1000); return 42;}) ;!Future<Integer> future = completionService.take();System.out.println(future.get()); // already completed…..
UserFuture
Executor ConsumerTask
Futures Evolution -‐ Java 7
•Java7 - jsr166y (Fork Join Pools) •Has a common pool •ForkJoinTask extends Future •Completion ?
ForkJoinTask<Integer> task = ForkJoinPool.commonPool(). submit( () -> { sleep(1000); System.out.printf("done"); }); System.out.println(task.get());
complete() a Complete mess
•With the method complete you can introduce a value before task competes. •But
ForkJoinTask<Integer> task = ForkJoinPool.commonPool(). submit(() -> { sleep(1000); return 42; }); ! sleep(10); task.complete(43); System.out.println(task.get()); task.complete(44); System.out.println(task.get()); sleep(2000); System.out.println(task.get());
43
42
44
Nothing
•Dinosaurs are perfect •They are big •Powerful •State of the art
Nothing, but evolution
Alternatives
•Akka Futures/Scala Futures •Scala Promises •Twitter - Finnagle •Guava ListenableFuture •Groovy Dataflow concurrency (GPars)
Proper Completion
•A correct way to complete a future. •Once a future is completed it immutable •It is IMPORTANT
Data-‐flow Concurrency
•If we have variables that can be written to once •We have deterministic behaviour! •Run it a million times it will still work the same!!!
Composition
•Looking for websites that will interest a group of people
Get Profile On linked in
user 1
Find intersection of skills
Get Profile On linked in
user 1
Get Profile On linked in
user n
search on google
Send mail with group recommendation
…….
CompletableFuture Is
•A container for a result that will become available at a later time •Backed by thread •May contain a Throwable if computation failed
CompletableFuture Is
•Means asynchronous •Does not mean non blocking •Does not mean reactive
Is Completable
•Is completed when completed! •The result can be set once. •Either by the task itself •Or from outside.
Is Composable
•Composable •Lambda expression friendly •More functional in it’s nature
CompletableFuture Creation
•supplyAsync •runAsync
import java.util.concurrent.CompletableFuture;import static java.util.concurrent.CompletableFuture.*;
CompletableFuture<Integer> f = supplyAsync( () -‐> {sleep(10000);return 42;} ); f.join();
Runs on ForkJoinPool.commonPool; You can supply an executor if you wantjoin is the same as get but throws an
unchecked exception (hip hip hurray)
Construction
•new CompletableFuture(); •use complete(r) to complete it •use completeExceptionally(t) to complete with an exception
CompletableFuture<Integer> a= new CompletableFuture<>();
a.complete(5); a.completeExceptionally(new IndexOutOfBoundsException());
CompletableFuture
•Implements CompletableStage •A large set of methods (~60 •Every method is multiplied by three •XXXX(….) •XXXXAsync(…) •XXXX(….,Executor x)
Future -‐> CompletableFuture
•Not really possible (Cleanly)
Future<Integer> future = ForkJoinPool.commonPool().submit( () -‐> {sleep(4000);return 42;} );! CompletableFuture<Integer> brighterFuture = supplyAsync(() -‐> { try { return future.get(); } catch (Exception e1) { throw new RuntimeException(e1); } }); System.out.println(brighterFuture.get());
Nasty Exception handling
Requires another thread….
!
thenApply
•Apply another action when result is available
CompletableFuture<Integer> f = supplyAsync( () -‐> {sleep(10000);return 42;});!CompletableFuture<Integer> f2 = f.thenApply((r) -‐> r*r);
CompletableFuture<Integer> f2 = f.thenApplyAsync((r) -‐> r*r);
CompletableFuture<Integer> f2 = f.thenApplyAsync((r) -‐> r*r, myLowPriorityExecutor);
Handling Exceptions
•exceptionally()
CompletableFuture<Integer> f = supplyAsync( () -‐> {sleep(10000); if (true) throw new RuntimeException(); return 42;});!CompletableFuture<Integer> f2 = f.exceptionally((t)-‐> 2). thenApply((r) -‐> r*r);System.out.println(f2.get());
The General Case
•handle() - gets result and throwable manipulates them •whenComplete() - does something, pass result through
CompletableFuture<Integer> f2 = f.handle( (res,throwable) -‐> (throwable==null)? res*res : 2); !CompletableFuture<Integer> f3 = f.whenComplete( (res, throwable) -‐> {System.out.println("done");});
Composition
•thenCompose() •Performs another stage upon completion •On failure stage will not be performed
CompletableFuture<Integer> f1 = supplyAsync( () -‐> {sleep(2100);return 42;});! CompletableFuture<Integer> f2 = f1.thenCompose( (v) -‐> supplyAsync(() -‐> {sleep(2100);return v+42;})) ; System.out.println(f2.get());
Combiners
•thenCombine() take both results and apply a function on them •thenAcceptBoth() - guess
CompletableFuture<Integer> f1 = supplyAsync( () -‐> {sleep(2100);return 42;}); CompletableFuture<Integer> f2 = supplyAsync( () -‐> {sleep(2100);return 55;});! CompletableFuture<Integer> f3 = f1.thenCombine(f2, (r1,r2) -‐> r1+r2) ; CompletableFuture<Void> f4 = f1.thenAcceptBoth(f2, (r1, r2) -‐> System.out.println(r1 + r2)) ; System.out.println(f3.get());
Either…
•thenApplyEither() take fastest result use it. Discard the second one •If exception is thrown behaviour is not predictable •Use case: parse fastest server result
CompletableFuture<Integer> f1 = supplyAsync( () -‐> {sleep(2300);return 42;}); CompletableFuture<Integer> f2 = supplyAsync( () -‐> {sleep(2200);return 43;});! CompletableFuture<Integer> f3 = f1.applyToEither(f2,(r) -‐> r * r);
A Better Either
•Hold down exceptions letting other futures a chance to complete
static<T> CompletableFuture<T> holdDownExceptionally(CompletableFuture<T>f, CountDownLatch latch) { return f.exceptionally((t) -‐> { try { latch.countDown();latch.await(); } catch (Exception e) { throw new RuntimeException(t); } throw new RuntimeException(t); }). thenApply((r) -‐> {latch.countDown();latch.countDown();return r;}); }
A Better Either cont
static <T,U> CompletableFuture<U>myApplytoEither(CompletableFuture<T> f1, CompletableFuture<T> f2, Function<? super T, U> fn) { CountDownLatch latch = new CountDownLatch(2); CompletableFuture<T> f1be = holdDownExceptionally(f1,latch); CompletableFuture<T> f2be = holdDownExceptionally(f2,latch); return f1be.applyToEither(f2be,fn);}
How Many?
•A completable future may have more than one dependents •Use getNumberOfDependents to get an estimate
CompletableFuture<Integer> f = supplyAsync( () -‐> {sleep(10000);return 42;});!CompletableFuture<Integer> f2 = f.thenApply((r) -‐> r*r);CompletableFuture<Integer> f3 = f.thenApply((r) -‐> r*r*r);CompletableFuture<Integer> f4 = f.thenApply((r) -‐> r*r*r*r);!f.getNumberOfDependents(); // returns 3
Helper Static Functions
•allOf(CompletableFuture<?>... cfs) •no value returned
•anyOf(CompletableFuture<?>... cfs) •object retured
NIO Non blocking IO
•Selectors •dispatchers •Reactor pattern •There is no support out of the box for CompletableFutures in NIO
What about J7 NIO2
•AsynchronousFileChannel •AsynchronousServerSocketChannel •Are using futures •Not adapted for completable futures.
AsynchronousFileChannel afc = AsynchronousFileChannel.open(Paths.get(“Video.avi"), StandardOpenOption.READ) ; ByteBuffer r = ByteBuffer.allocate(500*1024*1024) ; Future<Integer> a = afc.read(r,10*1024*1024); //do something useful while waiting a.get();
Further Info
•All examples can be found in github •https://github.com/lifey/compfut.git •Concurrency Interest Mailing List •Java Concurrency in Practice(Brian Goatz) •http://www.slideshare.net/kojilin/completable-future
Thanks + Q&A + Contact Me
© Copyright Performize-IT LTD.
http://il.linkedin.com/in/haimyadid
www.performize-it.com
blog.performize-it.com
https://github.com/lifey
@lifeyx