Top Banner
Overview of Advanced Java 8 CompletableFuture Features (Part 4) Douglas C. Schmidt [email protected] www.dre.vanderbilt.edu/~schmidt Professor of Computer Science Institute for Software Integrated Systems Vanderbilt University Nashville, Tennessee, USA
29

Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

Mar 15, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

Overview of Advanced Java 8

CompletableFuture Features (Part 4)

Douglas C. [email protected]

www.dre.vanderbilt.edu/~schmidt

Professor of Computer Science

Institute for Software

Integrated Systems

Vanderbilt University

Nashville, Tennessee, USA

Page 2: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

2

Learning Objectives in this Part of the Lesson• Understand advanced features

of completable futures, e.g.

• Factory methods that initiateasync functionality

• Completion stage methods usedto chain together actions that perform async result processing& composition

• Aribitrary-arity methods that process futures in bulk

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html

Exception methods

Completion stage methods

Factory methodsArbitrary-arity

methods

Basic methods

Page 3: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

3

Arbitrary-Arity Methods Process Futures in Bulk

Page 4: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

4

• Arbitrary-arity methods return futures that are triggered after completion of some/all futures

Methods Params Returns Behavior

allOf Varags CompletableFuture<Void>

Return a future that completes when all futures in paramscomplete

anyOf Varargs CompletableFuture<Void>

Return a future that completes when any future in paramscomplete

Arbitrary-Arity Methods Process Futures in Bulk

See en.wikipedia.org/wiki/Arity

Page 5: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

5

• Arbitrary-arity methods return futures that are triggered after completion of some/all futures

• The returned future can beused to wait for any or all of N completable futures in an array to complete

Arbitrary-Arity Methods Process Futures in Bulk

Page 6: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

6

• Arbitrary-arity methods return futures that are triggered after completion of some/all futures

• The returned future can beused to wait for any or all of N completable futures in an array to complete

Arbitrary-Arity Methods Process Futures in Bulk

These “arbitrary-arity” methods are hard to program without using wrappers

Page 7: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

7

• Arbitrary-arity methods return futures that are triggered after completion of some/all futures

• The returned future can beused to wait for any or all of N completable futures in an array to complete

Arbitrary-Arity Methods Process Futures in Bulk

We focus on allOf(), which is like thenCombine() on steroids!

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#allOf

Page 8: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

8

Arbitrary-Arity Methods Process Futures in Bulk• FuturesCollector returns a completable future to a list of big fractions that are

being reduced and multiplied asynchronously

static void testFractionMultiplications1() {

...

Stream.generate(() -> makeBigFraction(new Random(), false))

.limit(sMAX_FRACTIONS)

.map(reduceAndMultiplyFractions)

.collect(FuturesCollector.toFuture())

.thenAccept(this::sortAndPrintList);

}

See github.com/douglascraigschmidt/LiveLessons/tree/master/Java8/ex8

collect() converts a stream of completable futures into a single completable future

Page 9: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

9

Arbitrary-Arity Methods Process Futures in Bulk• FuturesCollector provides a wrapper for allOf()

See Java8/ex8/utils/FuturesCollector.java

Page 10: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

10FuturesCollector is a non-concurrent collector (supports parallel & sequential streams)

Arbitrary-Arity Methods Process Futures in Bulk• FuturesCollector provides a wrapper for allOf()

• Converts a stream of completable futures into a single completable future that’s triggered when all futures in the stream complete

Page 11: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

11

Arbitrary-Arity Methods Process Futures in Bulk• FuturesCollector provides a wrapper for allOf()

• Converts a stream of completable futures into a single completable future that’s triggered when all futures in the stream complete

• Implements the Collector interface thataccumulates input elements into a mutable result container

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

Page 12: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

12

Arbitrary-Arity Methods Process Futures in Bulk• FuturesCollector provides a wrapper for allOf()

FuturesCollector provides a powerful wrapper for some complex code!!!

Page 13: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

13

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

implements Collector<CompletableFuture<T>,

List<CompletableFuture<T>>,

CompletableFuture<List<T>>> {

...

• FuturesCollector provides a wrapper for allOf()

Implements a custom collector

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

Page 14: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

14

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

implements Collector<CompletableFuture<T>,

List<CompletableFuture<T>>,

CompletableFuture<List<T>>> {

...

• FuturesCollector provides a wrapper for allOf()

The type of input elements to the accumulator() method

Page 15: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

15

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

implements Collector<CompletableFuture<T>,

List<CompletableFuture<T>>,

CompletableFuture<List<T>>> {

...

• FuturesCollector provides a wrapper for allOf()

The mutable accumulation type of the accumulator() method

Page 16: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

16

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

implements Collector<CompletableFuture<T>,

List<CompletableFuture<T>>,

CompletableFuture<List<T>>> {

...

• FuturesCollector provides a wrapper for allOf()

The result type of the finisher() method, i.e., the final output of the collector

Page 17: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

17

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

implements Collector<CompletableFuture<T>,

List<CompletableFuture<T>>,

CompletableFuture<List<T>>> {

public Supplier<List<CompletableFuture<T>>> supplier() {

return ArrayList::new;

}

public BiConsumer<List<CompletableFuture<T>>,

CompletableFuture<T>> accumulator()

{ return List::add; }

...

• FuturesCollector provides a wrapper for allOf()

This factory method returns a supplier used by the Java 8 streams collector framework to create a new mutable array list container

Page 18: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

18

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

implements Collector<CompletableFuture<T>,

List<CompletableFuture<T>>,

CompletableFuture<List<T>>> {

public Supplier<List<CompletableFuture<T>>> supplier() {

return ArrayList::new;

}

public BiConsumer<List<CompletableFuture<T>>,

CompletableFuture<T>> accumulator()

{ return List::add; }

...

• FuturesCollector provides a wrapper for allOf()

This factory method returns a bi-consumer used by the Java 8 streams collector framework to add a new completable future into the mutable array list container

This method is only ever called in a single thread (so no locks are needed)

Page 19: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

19

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public BinaryOperator<List<CompletableFuture<T>>> combiner() {

return (List<CompletableFuture<T>> one,

List<CompletableFuture<T>> another) -> {

one.addAll(another);

return one;

};

}

...

• FuturesCollector provides a wrapper for allOf()

This factory method returns a binary operator that merges two partial array list results into a single array list (only relevant for parallel streams)

This method is only ever called in a single thread (so no locks are needed)

Page 20: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

20

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Function<List<CompletableFuture<T>>,

CompletableFuture<List<T>>> finisher() {

return futures -> CompletableFuture

.allOf(futures.toArray(new CompletableFuture[0]))

.thenApply(v -> futures.stream()

.map(CompletableFuture::join)

.collect(toList()));

}

...

• FuturesCollector provides a wrapper for allOf()

This factory method returns a function used by the Java 8 streams collector framework to transform the array list accumulation type to the completable future result type

Page 21: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

21

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Function<List<CompletableFuture<T>>,

CompletableFuture<List<T>>> finisher() {

return futures -> CompletableFuture

.allOf(futures.toArray(new CompletableFuture[0]))

.thenApply(v -> futures.stream()

.map(CompletableFuture::join)

.collect(toList()));

}

...

• FuturesCollector provides a wrapper for allOf()

Convert list of futures to array of futures & pass to allOf() to obtain a future that will complete when all futures complete

Page 22: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

22

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Function<List<CompletableFuture<T>>,

CompletableFuture<List<T>>> finisher() {

return futures -> CompletableFuture

.allOf(futures.toArray(new CompletableFuture[0]))

.thenApply(v -> futures.stream()

.map(CompletableFuture::join)

.collect(toList()));

}

...

• FuturesCollector provides a wrapper for allOf()

When all futures have completed get a single future to a list of joined elements of type T

Page 23: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

23

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Function<List<CompletableFuture<T>>,

CompletableFuture<List<T>>> finisher() {

return futures -> CompletableFuture

.allOf(futures.toArray(new CompletableFuture[0]))

.thenApply(v -> futures.stream()

.map(CompletableFuture::join)

.collect(toList()));

}

...

• FuturesCollector provides a wrapper for allOf()

Convert the array list of futures into a stream of futures

Page 24: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

24

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Function<List<CompletableFuture<T>>,

CompletableFuture<List<T>>> finisher() {

return futures -> CompletableFuture

.allOf(futures.toArray(new CompletableFuture[0]))

.thenApply(v -> futures.stream()

.map(CompletableFuture::join)

.collect(toList()));

}

...

• FuturesCollector provides a wrapper for allOf()

This call to join() will never block!

Page 25: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

25

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Function<List<CompletableFuture<T>>,

CompletableFuture<List<T>>> finisher() {

return futures -> CompletableFuture

.allOf(futures.toArray(new CompletableFuture[0]))

.thenApply(v -> futures.stream()

.map(CompletableFuture::join)

.collect(toList()));

}

...

• FuturesCollector provides a wrapper for allOf()

Return a future to a list of elements of T

Page 26: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

26

Arbitrary-Arity Methods Process Futures in Bulk• FuturesCollector is used to return a completable future to a list of big

fractions that are being reduced and multiplied asynchronously

static void testFractionMultiplications1() {

...

Stream.generate(() -> makeBigFraction(new Random(), false))

.limit(sMAX_FRACTIONS)

.map(reduceAndMultiplyFraction)

.collect(FuturesCollector.toFuture())

.thenAccept(this::sortAndPrintList);

}

See github.com/douglascraigschmidt/LiveLessons/tree/master/Java8/ex8

thenAccept() is called only when the future returned from collect() completes

Page 27: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

27

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Set characteristics() {

return Collections.singleton(Characteristics.UNORDERED);

}

public static <T> Collector<CompletableFuture<T>, ?,

CompletableFuture<List<T>>>

toFuture() {

return new FuturesCollector<>();

}

}

• FuturesCollector provides a wrapper for allOf()

Returns a set indicating the characteristics of FutureCollector

FuturesCollector is thus a non-concurrent collector

Page 28: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

28

Arbitrary-Arity Methods Process Futures in Bulk

public class FuturesCollector<T>

...

public Set characteristics() {

return Collections.singleton(Characteristics.UNORDERED);

}

public static <T> Collector<CompletableFuture<T>, ?,

CompletableFuture<List<T>>>

toFuture() {

return new FuturesCollector<>();

}

}

• FuturesCollector provides a wrapper for allOf()

Static factory method creates a new FuturesCollector

Page 29: Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of the Lesson •Understand advanced features of completable futures, e.g. •Factory

29

End of Overview of Advanced Java 8 Completable Future

Features (Part 4)