Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010...
Transcript of Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010...
![Page 1: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/1.jpg)
![Page 2: Asynchronous API with CompletableFuture · Aboutme JavaPerformanceEngineeratOracle,@since2010 JavaPerformanceEngineer,@since2005 JavaEngineer,@since1996 OpenJDK/OracleJVMisthethirdJVMinmyexperience](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/2.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/3.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/4.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/5.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/6.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/7.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/8.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/9.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/10.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/11.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/12.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/13.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/14.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/15.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/16.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/17.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/18.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/19.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/20.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/21.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/22.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/23.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/24.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/25.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/26.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/27.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/28.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/29.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/30.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/31.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/32.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/33.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/34.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/35.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/36.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/37.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/38.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/39.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/40.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/41.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/42.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/43.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/44.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/45.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/46.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/47.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/48.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/49.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/50.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/51.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/52.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/53.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/54.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/55.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/56.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/57.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/58.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/59.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/60.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/61.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/62.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/63.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/64.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/65.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/66.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/67.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/68.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/69.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/70.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/71.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/72.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/73.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/74.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/75.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/76.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/77.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/78.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/79.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/80.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/81.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/82.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/83.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/84.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/85.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/86.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/87.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/88.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/89.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/90.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/91.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/92.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/93.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/94.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/95.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/96.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/97.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/98.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/99.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/100.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/101.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/102.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/103.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/104.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/105.jpg)
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](https://reader034.fdocuments.in/reader034/viewer/2022042106/5e84ca0f14f146768a1cf75e/html5/thumbnails/106.jpg)
86