pros & cons of java 8 completablefuturesschmidt/cs891f/2018-pdfs/17-pros... · 2018-11-17 ·...
TRANSCRIPT
Pros & Cons of Java 8 CompletableFutures
Douglas C. [email protected]
www.dre.vanderbilt.edu/~schmidt
Professor of Computer Science
Institute for Software
Integrated Systems
Vanderbilt University
Nashville, Tennessee, USA
2
Learning Objectives in this Part of the Lesson• Understand the pros & cons of using
the completable futures framework
4No explicit synchronization or threading is required in this implementation
Pros & Cons of Java 8 Completable FuturesCompletable Futures
…
map(this::downloadImageAsync)
thenAccept(this::logResults)
flatMap(this::applyFiltersAsync)
collect(toFuture())
map(this::checkUrlCachedAsync)
5Java libraries handle any locking needed to protect shared mutable state
Pros & Cons of Java 8 Completable FuturesCompletable Futures
…
map(this::downloadImageAsync)
thenAccept(this::logResults)
flatMap(this::applyFiltersAsync)
collect(toFuture())
map(this::checkUrlCachedAsync)
6
• We’ll now evaluate the Java 8 completable futures framework compared with the parallel streams framework
Pros & Cons of Java 8 Completable Futures
See github.com/douglascraigschmidt/LiveLessons/tree/master/ImageStreamGang
Completable Futures
…
map(this::downloadImageAsync)
thenAccept(this::logResults)
flatMap(this::applyFiltersAsync)
collect(toFuture())
map(this::checkUrlCachedAsync)
collect(toList())
Parallel Streams
…
filter(not(this::urlCached))
map(this::downloadImage)
flatMap(this::applyFilters)
7
void processStream() {
List<URL> urls = getInput();
CompletableFuture<Stream<Image>>
resultsFuture = urls
.stream()
.map(this::checkUrlCachedAsync)
.map(this::downloadImageAsync)
.flatMap(this::applyFiltersAsync)
.collect(toFuture())
.thenApply(this::logResults)
.join();
...
Pros & Cons of Java 8 Completable Futures• It’s easier to program Java 8 parallel streams than completable futures
In general, asynchrony patterns aren’t as well understood by many developers
void processStream() {
List<URL> urls = getInput();
List<Image> filteredImages =
urls
.parallelStream()
.filter(not(this::urlCached))
.map(this::blockingDownload)
.flatMap(this::applyFilters)
.collect(toList());
logResults(filteredImages);
}
8
Pros & Cons of Java 8 Completable Futures
Performance Productivity
• There's a tradeoff between computing performance & programmer productivity when choosing amongst these frameworks
Printing results for input 1 from fastest to slowestCOMPLETABLE_FUTURES_2 executed in 276 msecsCOMPLETABLE_FUTURES_1 executed in 285 msecsPARALLEL_STREAM executed in 383 msecsSEQUENTIAL_STREAM executed in 1288 msecs
Printing results for input 2 from fastest to slowestCOMPLETABLE_FUTURES_1 executed in 137 msecsCOMPLETABLE_FUTURES_2 executed in 138 msecsPARALLEL_STREAM executed in 170 msecsSEQUENTIAL_STREAM executed in 393 msecs
9
Printing results for input 1 from fastest to slowestCOMPLETABLE_FUTURES_2 executed in 276 msecsCOMPLETABLE_FUTURES_1 executed in 285 msecsPARALLEL_STREAM executed in 383 msecsSEQUENTIAL_STREAM executed in 1288 msecs
Printing results for input 2 from fastest to slowestCOMPLETABLE_FUTURES_1 executed in 137 msecsCOMPLETABLE_FUTURES_2 executed in 138 msecsPARALLEL_STREAM executed in 170 msecsSEQUENTIAL_STREAM executed in 393 msecs
Pros & Cons of Java 8 Completable Futures• There's a tradeoff between computing performance & programmer
productivity when choosing amongst these frameworks, e.g.
• Completable futures are more efficient & scalable, but are harder to program
Performance
Productivity
10
Performance
Productivity
Pros & Cons of Java 8 Completable Futures• There's a tradeoff between computing performance & programmer
productivity when choosing amongst these frameworks, e.g.
• Completable futures are more efficient & scalable, but are harder to program
• Parallel streams are often easier to program, but are less efficient &scalable
11
Pros & Cons of Java 8 Completable Futures• There's a tradeoff between computing performance & programmer
productivity when choosing amongst these frameworks, e.g.
• Completable futures are more efficient & scalable, but are harder to program
• Parallel streams are often easier to program, but are less efficient &scalable
• Combining sequential streams & completable futures is often a win
Completable Futures
…
map(this::downloadImageAsync)
thenAccept(this::logResults)
flatMap(this::applyFiltersAsync)
collect(toFuture())
map(this::checkUrlCachedAsync)
12
Pros & Cons of Java 8 Completable Futures• There's a tradeoff between computing performance & programmer
productivity when choosing amongst these frameworks, e.g.
• Completable futures are more efficient & scalable, but are harder to program
• Parallel streams are often easier to program, but are less efficient &scalable
• Combining sequential streams & completable futures is often a win
• However, it’s overkill to combine parallel streams & completablefutures
13
CompletableFuture
.supplyAsync(
() -> findBestPrice("LDN - NYC"),
executorService)
.thenCombine(CompletableFuture
.supplyAsync
(() -> queryExchangeRateFor("GBP")),
this::convert)
.orTimeout(1, TimeUnit.SECONDS)
.whenComplete((amount, ex) -> {
if (ex == null)
{ System.out.println("The price is: " + amount + "GBP"); }
else { System.out.println(ex.getMessage()); }
});
Pros & Cons of Java 8 Completable Futures• Java 9 fixes some completable future limitations
See iteratrlearning.com/java9/2016/09/13/java9-timeouts-completablefutures.html