asynchronous api with completablefuture · aboutme javaperformanceengineeratoracle,@since2010...

106

Upload: others

Post on 24-Mar-2020

15 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience
Page 2: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Asynchronous API withCompletableFuturePerformance Tips and Tricks

Sergey KuksenkoJava Platform Group, OracleNovember, 2017

Page 3: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Safe Harbor Statement

The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.

Page 4: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

About me

• Java Performance Engineer at Oracle, @since 2010• Java Performance Engineer, @since 2005• Java Engineer, @since 1996• OpenJDK/OracleJVM is the third JVM in my experience• Co-author of JMH (Java Microbenchmark Harness)

Page 5: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• @since Java8

• Not used in Java8

5

Page 6: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• @since Java8• Not used in Java8

5

Page 7: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• @since Java8• Not used in Java8

5

Page 8: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• @since Java8• Not used in Java8

5

Page 9: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• Usage in Java9:

– Process API

– HttpClient*

*Most tips are from here!

6

Page 10: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

HttpClient

(a.k.a. JEP-110)

7

Page 11: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

HttpClient a.k.a. JEP-110

• Part of JDK 9, but not included into Java SE

– module: jdk.incubator.httpclient– package: jdk.incubator.http

• Incubator Modules a.k.a. JEP-11

– «The incubation lifetime of an API is limited: It is expected that theAPI will either be standardized or otherwise made final in the nextrelease, or else removed»

8

Page 12: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

HttpClient a.k.a. JEP-110

• Part of JDK 9, but not included into Java SE

– module: jdk.incubator.httpclient– package: jdk.incubator.http

• Incubator Modules a.k.a. JEP-11

– «The incubation lifetime of an API is limited: It is expected that theAPI will either be standardized or otherwise made final in the nextrelease, or else removed»

8

Page 13: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

HttpClient

Two ways to send request:

• synchronous/blocking• asynchronous

9

Page 14: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

synchronous/blocking

HttpClient client = «create client»;HttpRequest request = «create request»;

HttpResponse<String> response =

client.send(request, BodyHandler.asString());

if (response.statusCode() == 200) {System.out.println("We’ve got: " + response.body());

}

...

10

Page 15: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

asynchronous

HttpClient client = «create client»;HttpRequest request = «create request»;

CompletableFuture<HttpResponse<String>> futureResponse =

client.sendAsync(request, BodyHandler.asString());

futureResponse.thenAccept( response -> {if (response.statusCode() == 200) {

System.out.println("We’ve got: " + response.body());}

});...

11

Page 16: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Client builder

HttpClient client = HttpClient.newBuilder().authenticator(someAuthenticator).sslContext(someSSLContext).sslParameters(someSSLParameters).proxy(someProxySelector).executor(someExecutorService).followRedirects(HttpClient.Redirect.ALWAYS).cookieManager(someCookieManager).version(HttpClient.Version.HTTP_2).build();

Good habit for async API

12

Page 17: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

First step of performance:

developers!

13

Page 18: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

First step of performance:

developers!

13

Page 19: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What about Java developers performance?

14

Page 20: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• contains 38 methods

• 36 of them has 3 forms:

– somethingAsync(..., executor)

– somethingAsync(...)

– something(...)

15

Page 21: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• somethingAsync(..., executor)– runs action chain in the executor

• somethingAsync(...)– somethingAsync(..., ForkJoinPool.commonPool())

• something(...)– default execution ?

?will talk about this later 16

Page 22: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• 12 methods remained

• 9 of them has 3 forms:

– Apply – function from input to R, result CompletableFuture<R>

– Accept – consumer of input, result CompletableFuture<Void>

– Run – just execute Runnable, result CompletableFuture<Void>

17

Page 23: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• single input

– thenApply, thenAccept, thenRun

• binary «or»

– applyToEither, acceptEither, runAfterEither

• binary «and»

– thenCombine, thenAcceptBoth, runAfterBoth

18

Page 24: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• 3 methods remained

– thenCompose

– handle

– whenComplete

19

Page 25: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• thenCompose

– function from input to CompletableFuture<R>,result CompletableFuture<R>

– a.k.a flatMap

20

Page 26: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• handle

– function from input and exception to R,result CompletableFuture<R>

21

Page 27: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• whenComplete

– consumer from input and exception

– similar to Accept methods above

– result - the same as input

22

Page 28: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletionStage

• 2 methods remained (does’t have async versions)

– exceptionally - function from exception to R,result CompletableFuture<R>

– toCompletableFuture

23

Page 29: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• contains 38 methods inherited from CompletionStage

and

• 22 other instance methods

• 12 static methods

24

Page 30: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• 9 ways to complete future

– complete/completeAsync/completeExeceptionally

– cancel

– obtrudeValue/obtrudeException

– completeOnTimeout/orTimeout

25

Page 31: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• 4 ways to get value

– get/join – blocking

– get(timeout, timeUnit) – not so blocking

– getNow(valueIfAbsent) – non-blocking

26

Page 32: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• 3 ways to know status

– isDone

– isCompletedExceptionally

– isCancelled

27

Page 33: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

j.u.c.CompletableFuture

• 8 static methods to create future

– completedFuture/completedStage

– failedFuture/failedStage

– runAsync(Runnable) → CompletableFuture<Void>

– supplyAsync(Supplier<U>) → CompletableFuture<U>

28

Page 34: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Blocking or asynchronous?

29

Page 35: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Blocking or asynchronous

• Blocking:

– R doSmth(...);

• Asynchronous:

– CompletableFuture<R> doSmthAsync(...);

30

Page 36: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Yin and yang Blocking and asynchronous

R doSmth(...);

CompletableFuture<R> doSmthAsync(...);

CompletableFuture.supplyAsync(() -> doSmth(...));

doSmthAsync(...).join();

31

Page 37: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Blocking via async

R doSmth(...) {return doSmthAsync(...).join();

}

Will it work?

32

Page 38: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

doSmth

doSmthAsync

join

work

33

Page 39: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s measure

34

Page 40: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s measure

34

Page 41: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s measure

34

Page 42: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Avoid transition task from one thread to another.It costs.

35

Page 43: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Async via blocking

CompletableFuture<R> doSmthAsync(...) {return CompletableFuture.supplyAsync(()->doSmth(...), executor);

}

Will it work?

36

Page 44: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Back to HttpClient

public <T> HttpResponse<T>send(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler) {

...}

public <T> CompletableFuture<HttpResponse<T>>sendAsync(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler) {

return CompletableFuture.supplyAsync(() -> send(req, responseHandler), executor);}

Will it work?

37

Page 45: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Back to HttpClient

public <T> HttpResponse<T>send(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler) {

...}

public <T> CompletableFuture<HttpResponse<T>>sendAsync(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler) {

return CompletableFuture.supplyAsync(() -> send(req, responseHandler), executor);}

Sometimes.

37

Page 46: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

One does not simply make «sendAsync»

• send header• send body• receive header from server• receive body from server

38

Page 47: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

One does not simply make «sendAsync»

• send header• send body• wait header from server• wait body from server

38

Page 48: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

39

Page 49: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

wait/await

39

Page 50: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

wait/await

receiveResponse

notify/signal

39

Page 51: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

wait/await

receiveResponse

notify/signal

39

Page 52: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

wait/await

receiveResponse

notify/signal

DON’T!

39

Page 53: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

wait/await

Aux threads

receiveResponse

notify/signal

processResponse

39

Page 54: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

RTFM (HttpClient.Builder)

/*** Sets the executor to be used for asynchronous tasks. If this method is* not called, a default executor is set, which is the one returned from* {@link java.util.concurrent.Executors#newCachedThreadPool()* Executors.newCachedThreadPool}.** @param executor the Executor* @return this builder*/public abstract Builder executor(Executor executor);

If not explicitly stated otherwise, async APIshould be able to work with any kind of executor.

40

Page 55: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

RTFM (java.util.concurrent.Executors)/*** Creates a thread pool that creates new threads as needed, but* will reuse previously constructed threads when they are* available. These pools will typically improve the performance* of programs that execute many short-lived asynchronous tasks.* Calls to {@code execute} will reuse previously constructed* threads if available. If no existing thread is available, a new* thread will be created and added to the pool. Threads that have* not been used for sixty seconds are terminated and removed from* the cache. Thus, a pool that remains idle for long enough will* not consume any resources. Note that pools with similar* properties but different details (for example, timeout parameters)* may be created using {@link ThreadPoolExecutor} constructors.** @return the newly created thread pool*/public static ExecutorService newCachedThreadPool()

41

Page 56: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

CachedThreadPool

• Pro:– If all threads are busy, the task will be executed in a new thread

• Con:– If all threads are busy, a new thread is created

42

Page 57: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

sendAsync via send

The single HttpRequest uses ∼ 20 threads.

Does it mean that

100 simultaneous requests ⇒ ∼ 2000 threads?

a

100 simultaneous requests ⇒ OutOfMemoryError!

43

Page 58: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

sendAsync via send

The single HttpRequest uses ∼ 20 threads.

Does it mean that

100 simultaneous requests ⇒ ∼ 2000 threads?

a

100 simultaneous requests ⇒ OutOfMemoryError!

43

Page 59: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Eliminate waiting (step 1)

CompletableFuture as a single-use Condition.

Executor thread

Condition responseReceived;

R send(...) {sendRequest(...);responseReceived.await();processResponse();...

}

Aux thread

... receiveResponse(...) {...responseReceived.signal();...

}

A

44

Page 60: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Eliminate waiting (step 1)

CompletableFuture as a single-use Condition.

Executor thread

CompletableFuture<...> responseReceived;

R send(...) {sendRequest(...);responseReceived.join();processResponse();...

}

Aux thread

... receiveResponse(...) {...responseReceived.complete();...

}

A

45

Page 61: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Eliminate waiting (step 2)

CompletableFuture<...> sendAsync(...) {return CompletableFuture.supplyAsync(() -> send(...));

}

R send(...) {sendRequest(...);responseReceived.join();return processResponse();

}

46

Page 62: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Eliminate waiting (step 2)

CompletableFuture<...> sendAsync(...) {return CompletableFuture.supplyAsync(() -> sendRequest(...))

.thenApply((...) -> responseReceived.join())

.thenApply((...) -> processResponse());}

A

47

Page 63: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Eliminate waiting (step 2)

CompletableFuture<...> sendAsync(...) {return CompletableFuture.supplyAsync(() -> sendRequest(...))

.thenCompose((...) -> responseReceived)

.thenApply((...) -> processResponse());}

A

48

Page 64: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads Executor threads

sendAsync

supplyAsyncsend

thenCompose

Aux threads

futurereceiveResponse

complete

processResponse

49

Page 65: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What about sendAsync performance?

wait()/await() elimination⇓

+40%

50

Page 66: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Avoid blocking inside CompletableFuture chains.It costs.

51

Page 67: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Quiz

Thread 1

future.thenApply((...) -> foo());

Thread 2

future.complete(...);

Which thread will execute foo()?A) thread 1B) thread 2C) thread 1 or thread 2D) thread 1 and thread 2

52

Page 68: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Quiz

Thread 1

future.thenApply((...) -> foo());

Thread 2

future.complete(...);

Which thread will execute foo()?A) thread 1B) thread 2C) thread 1 or thread 2D) thread 1 and thread 2

correct answer

52

Page 69: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Where exactly CompletableFuture chain of

actions will be executed?

53

Page 70: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Two simple rules

(not always work)

• Completion thread executes actions attached «long enough»before completion.

• Construction thread executes actions if CompletableFuture isalready completed («long enough» before).

Races are coming!

54

Page 71: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Two simple rules (not always work)

• Completion thread executes actions attached «long enough»before completion.

• Construction thread executes actions if CompletableFuture isalready completed («long enough» before).

Races are coming!

54

Page 72: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Chain of actions may be executed from:

• Completion thread

– complete, completeExceptionally ...

• Construction thread

– thenApply, thenCompose ...

• Value getting thread

– get, join ...

55

Page 73: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s check!

56

Page 74: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

jsctress

http://openjdk.java.net/projects/code-tools/jcstress/

The Java Concurrency Stress tests (jcstress) is an experimentalharness and a suite of tests to aid the research in the correctness ofconcurrency support in the JVM, class libraries, and hardware.

57

Page 75: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Example 1

CompletableFuture<...> start =new CompletableFuture<>();

start.complete(...); start.thenApply(a -> action());

Results:

Occurrences Expectation Interpretation1,630,058,138 ACCEPTABLE action in chain construction thread197,470,850 ACCEPTABLE action in completion thread

58

Page 76: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Example 2

CompletableFuture<...> start =new CompletableFuture<>();

start.thenApply(a -> action());start.complete(...); start.complete(...);

Results:

Occurrences Expectation Interpretation819,755,198 ACCEPTABLE action in successful completion thread163,205,510 ACCEPTABLE action in failed completion thread

59

Page 77: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Example 3

CompletableFuture<...> start =new CompletableFuture<>();

start.thenApply(a -> action());start.complete(...); start.join();

Results:

Occurrences Expectation Interpretation904,651,258 ACCEPTABLE action in completion thread300,524,840 ACCEPTABLE action in join thread

60

Page 78: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Example 4

CompletableFuture<...> start =new CompletableFuture<>();

start.thenApply(a -> action1());start.thenApply(a -> action2());

start.complete(...); start.join();

Results:Occurrences Expectation Interpretation179,525,918 ACCEPTABLE both actions in the same thread276,608,380 ACCEPTABLE actions in different threads

61

Page 79: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What is faster?

Same thread chainfuture.thenApply((...) -> foo1()).thenApply((...) -> foo2())

Async chainfuture.thenApplyAsync((...) -> foo1(), executor).thenApplyAsync((...) -> foo2(), executor);

62

Page 80: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s measure

63

Page 81: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s measure

63

Page 82: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s measure

63

Page 83: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

CompletableFuture chaining

• thenSomethingAsync(...) – gives predictability.• thenSomething(...) – gives performance.

64

Page 84: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Avoid transition task from one thread to another.It costs.

65

Page 85: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

When predictability is important

HttpClient has the single auxiliary thread «SelectorManager».

• waits on Selector.select• reads data from Socket• extracts HTTP2 frames• distributes frames to receivers

66

Page 86: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads

sendAsync

Executor threads

thenCompose

thenApply(foo)

thenApply(bar)

SelectorManager

future

receiveResponse

complete

foo

bar

67

Page 87: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

User threads

sendAsync

Executor threads

thenCompose

thenApply(foo)

thenApply(bar)

SelectorManager

future

receiveResponse

complete

foo

bar

foo

barDON’T!

67

Page 88: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

When predictability is important

CompletableFuture<...> response;

Executor thread «SelectorManager»

...

.thenCompose(() -> response) response.complete(...);

...

ee

68

Page 89: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

One way (@since 9)

CompletableFuture<...> response;

Executor thread «SelectorManager»

...

.thenCompose(() -> response) response.completeAsync(..., executor);

...

ee

69

Page 90: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Another way

CompletableFuture<...> response;

Executor thread «SelectorManager»

...

.thenComposeAsync(() -> response, executor) response.complete(...);

...

ee

70

Page 91: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What we’ve got (in both cases)

• Pro:– «SelectorManager» is protected

• Con:– Switching from one executor thread to another executor thread

(costs).

71

Page 92: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Third way

CompletableFuture<...> response;

Executor thread «SelectorManager»

CompletableFuture<...> cf = response;if(!cf.isDone()) { response.complete(...);

cf = cf.thenApplyAsync(x -> x, executor);}...thenCompose(() -> cf);...

ee

72

Page 93: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What about sendAsync performance?

Tuning complete()

⇓+16%

73

Page 94: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Carefully avoid transition taskfrom one thread to another.

It costs.

74

Page 95: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What if server responds quickly?

CompletableFuture<...> sendAsync(...) {returnsendHeaderAsync(..., executor).thenCompose(() -> sendBody()).thenCompose(() -> getResponseHeader()).thenCompose(() -> getResponseBody())...

}

Sometimes (3% cases)

CompletableFuture

is already completed

getResponseBody() is executed from user thread

75

Page 96: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

We have thenComposeAsync()

• Pro:– User thread is protected

• Con:– Switching from one executor thread to another executor thread

(costs).

76

Page 97: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Do it

CompletableFuture<...> sendAsync(...) {CompletableFuture<Void> start = new CompletableFuture<>();

CompletableFuture<...> end = start.thenCompose(v -> sendHeader()).thenCompose(() -> sendBody()).thenCompose(() -> getResponseHeader()).thenCompose(() -> getResponseBody())...;

start.completeAsync(() -> null, executor); // trigger executionreturn end;

}

77

Page 98: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

What about sendAsync performance?

Delayed start⇓

+10%

78

Page 99: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

It may be useful to build chain of actions beforeexecution.

79

Page 100: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Let’s back to CachedThreadPool

• Pro:– If all threads are busy, the task will be executed in a new thread

• Con:– If all threads are busy, a new thread is created

Is that a good choice for the default executor?

80

Page 101: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Try different executors

CachedThreadPool 35500 ops/sec

FixedThreadPool(2) 61300 ops/sec

+72%

81

Page 102: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Different ThreadPools show different performance.

82

Page 103: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Q & A ?

83

Page 104: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

Appendix

84

Page 105: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.

another example of thenCompose

// e.g. how to make recursive CompletableFuture chain

CompletableFuture<...> makeRecursiveChain(...) {if(«recursion ends normally») {

return CompletableFuture.completedFuture(...);else if(«recursion ends abruptly») {

return CompletableFuture.failedFuture(...); // appeared in Java9}return CompletableFuture.supplyAsync(() -> doSomething(...))

.thenCompose((...) -> makeRecursiveChain(...));}

A

85

Page 106: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience

86