Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of...

29
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

Transcript of Overview of Advanced Java 8 CompletableFuture Features ... · 2 Learning Objectives in this Part of...

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)