51
Applying Java 8 Functional Programming Features to a Parallel Program Douglas C. Schmidt [email protected] www.dre.vanderbilt.edu/~schmidt Professor of Computer Science Institute for Software Integrated Systems Vanderbilt University Nashville, Tennessee, USA

Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

  • Upload
    others

  • View
    15

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

Applying Java 8 Functional Programming

Features to a Parallel Program

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: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

2

Learning Objectives in this Lesson• Understand how Java 8 functional programming

features are applied in a simple parallel program

See github.com/douglascraigschmidt/LiveLessons/tree/master/ThreadJoinTest/updated

Starting SearchStreamin thread 23 the phrase "Anon," was found at character offset 111628 in "The First Part of Henry VI"in thread 20 the phrase "Anon," was found at character offset 30949 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 48850 in "The First Part of King Henry IV"in thread 19 the phrase "Anon," was found at character offset 170485 in "The Tragedy of Hamlet"in thread 20 the phrase "Anon," was found at character offset 49402 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 49640 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50003 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50140 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50464 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50486 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 51628 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 52190 in "The First Part of King Henry IV"in thread 21 the phrase "Anon," was found at character offset 67832 in "Second Part of King Henry IV"in thread 16 the phrase "Anon," was found at character offset 75139 in "The Comedy of Errors"in thread 16 the phrase "Anon," was found at character offset 76511 in "The Comedy of Errors"in thread 31 the phrase "Anon," was found at character offset 34971 in "The Tragedy of Macbeth"in thread 40 the phrase "Anon," was found at character offset 37045 in "The Tragedy of Romeo & Juliet"in thread 40 the phrase "Anon," was found at character offset 46837 in "The Tragedy of Romeo & Juliet"Ending SearchStream

Page 3: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

3

Learning Objectives in this Lesson• Understand how Java 8 functional programming

features are applied in a simple parallel program

• This program searches for a list of phrases in the complete works of William Shakespeare

Starting SearchStreamin thread 23 the phrase "Anon," was found at character offset 111628 in "The First Part of Henry VI"in thread 20 the phrase "Anon," was found at character offset 30949 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 48850 in "The First Part of King Henry IV"in thread 19 the phrase "Anon," was found at character offset 170485 in "The Tragedy of Hamlet"in thread 20 the phrase "Anon," was found at character offset 49402 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 49640 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50003 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50140 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50464 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50486 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 51628 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 52190 in "The First Part of King Henry IV"in thread 21 the phrase "Anon," was found at character offset 67832 in "Second Part of King Henry IV"in thread 16 the phrase "Anon," was found at character offset 75139 in "The Comedy of Errors"in thread 16 the phrase "Anon," was found at character offset 76511 in "The Comedy of Errors"in thread 31 the phrase "Anon," was found at character offset 34971 in "The Tragedy of Macbeth"in thread 40 the phrase "Anon," was found at character offset 37045 in "The Tragedy of Romeo & Juliet"in thread 40 the phrase "Anon," was found at character offset 46837 in "The Tragedy of Romeo & Juliet"Ending SearchStream

See shakespeare.mit.edu

Page 4: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

4

Learning Objectives in this Lesson• Understand how Java 8 functional programming

features are applied in a simple parallel program

• Recognize the pros & cons of usingJava 8 features in this example

These “cons” help to motivate the need for Java 8 parallelism frameworks

Page 5: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

5

Example of Starting & Joining Java Threads

with Java 8

Page 6: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

6

Example of Starting & Joining Java Threads with Java 8

See github.com/douglascraigschmidt/LiveLessons/tree/master/ThreadJoinTest/updated

• Use Java 8 features to start() & join() a group of threads to search for phrases in the works of William Shakespeare

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(thread ->

{ try { thread.join(); }

catch (Exception e)

{ throw new RuntimeException(e);

}});

Starting SearchStreamin thread 23 the phrase "Anon," was found at character offset 111628 in "The First Part of Henry VI"in thread 20 the phrase "Anon," was found at character offset 30949 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 48850 in "The First Part of King Henry IV"in thread 19 the phrase "Anon," was found at character offset 170485 in "The Tragedy of Hamlet"in thread 20 the phrase "Anon," was found at character offset 49402 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 49640 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50003 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50140 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50464 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50486 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 51628 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 52190 in "The First Part of King Henry IV"in thread 21 the phrase "Anon," was found at character offset 67832 in "Second Part of King Henry IV"in thread 16 the phrase "Anon," was found at character offset 75139 in "The Comedy of Errors"in thread 16 the phrase "Anon," was found at character offset 76511 in "The Comedy of Errors"in thread 31 the phrase "Anon," was found at character offset 34971 in "The Tragedy of Macbeth"in thread 40 the phrase "Anon," was found at character offset 37045 in "The Tragedy of Romeo & Juliet"in thread 40 the phrase "Anon," was found at character offset 46837 in "The Tragedy of Romeo & Juliet"Ending SearchStream

Page 7: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

7

Example of Starting & Joining Java Threads with Java 8• This program is "embarrassingly parallel"

See en.wikipedia.org/wiki/Embarrassingly_parallel

Starting SearchStreamin thread 23 the phrase "Anon," was found at character offset 111628 in "The First Part of Henry VI"in thread 20 the phrase "Anon," was found at character offset 30949 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 48850 in "The First Part of King Henry IV"in thread 19 the phrase "Anon," was found at character offset 170485 in "The Tragedy of Hamlet"in thread 20 the phrase "Anon," was found at character offset 49402 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 49640 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50003 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50140 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50464 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50486 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 51628 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 52190 in "The First Part of King Henry IV"in thread 21 the phrase "Anon," was found at character offset 67832 in "Second Part of King Henry IV"in thread 16 the phrase "Anon," was found at character offset 75139 in "The Comedy of Errors"in thread 16 the phrase "Anon," was found at character offset 76511 in "The Comedy of Errors"in thread 31 the phrase "Anon," was found at character offset 34971 in "The Tragedy of Macbeth"in thread 40 the phrase "Anon," was found at character offset 37045 in "The Tragedy of Romeo & Juliet"in thread 40 the phrase "Anon," was found at character offset 46837 in "The Tragedy of Romeo & Juliet"Ending SearchStream

Page 8: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

8

Example of Starting & Joining Java Threads with Java 8• This program is "embarrassingly parallel"

• i.e., there are no data dependencies between worker threads

See en.wikipedia.org/wiki/Embarrassingly_parallel

Starting SearchStreamin thread 23 the phrase "Anon," was found at character offset 111628 in "The First Part of Henry VI"in thread 20 the phrase "Anon," was found at character offset 30949 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 48850 in "The First Part of King Henry IV"in thread 19 the phrase "Anon," was found at character offset 170485 in "The Tragedy of Hamlet"in thread 20 the phrase "Anon," was found at character offset 49402 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 49640 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50003 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50140 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50464 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 50486 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 51628 in "The First Part of King Henry IV"in thread 20 the phrase "Anon," was found at character offset 52190 in "The First Part of King Henry IV"in thread 21 the phrase "Anon," was found at character offset 67832 in "Second Part of King Henry IV"in thread 16 the phrase "Anon," was found at character offset 75139 in "The Comedy of Errors"in thread 16 the phrase "Anon," was found at character offset 76511 in "The Comedy of Errors"in thread 31 the phrase "Anon," was found at character offset 34971 in "The Tragedy of Macbeth"in thread 40 the phrase "Anon," was found at character offset 37045 in "The Tragedy of Romeo & Juliet"in thread 40 the phrase "Anon," was found at character offset 46837 in "The Tragedy of Romeo & Juliet"Ending SearchStream

Page 9: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

10

Example of Starting & Joining Java Threads with Java 8

List<String> mInputList =

TestDataFactory.getInput

(sSHAKESPEARE_DATA_FILE,

"@");

...

@The Tragedy of Hamlet

...

@The Tragedy of Julius Caesar

...

@The Tragedy of Macbeth

...

Each work begins with a ’@’ character

• The program obtains the complete worksof Shakespeare & a list of phrases fromtwo text files

Page 10: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

11

Example of Starting & Joining Java Threads with Java 8

List<String> mPhrasesToFind =

TestDataFactory.getPhraseList

(sPHRASE_LIST_FILE);

...

Neither a borrower nor a lender be

Beware the Ides of March

Brevity is the soul of wit

All that glisters is not gold

Sit you down, father; rest you

my kingdom for a horse!

...

Each phrase appears on a separate line

• The program obtains the complete worksof Shakespeare & a list of phrases fromtwo text files

Page 11: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

12

• Return the input data in the given file as an array of strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getInput(String file, String splitter) {

URI uri = ClassLoader.getSystemResource(file).toURI();

String bytes = new String(Files.readAllBytes

(Paths.get(uri)));

return Pattern

.compile(splitter)

.splitAsStream(bytes)

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Page 12: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

13

• Return the input data in the given file as an array of strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getInput(String file, String splitter) {

URI uri = ClassLoader.getSystemResource(file).toURI();

String bytes = new String(Files.readAllBytes

(Paths.get(uri)));

return Pattern

.compile(splitter)

.splitAsStream(bytes)

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Convert the file name into a path name

Page 13: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

14

• Return the input data in the given file as an array of strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getInput(String file, String splitter) {

URI uri = ClassLoader.getSystemResource(file).toURI();

String bytes = new String(Files.readAllBytes

(Paths.get(uri)));

return Pattern

.compile(splitter)

.splitAsStream(bytes)

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Open the file & read all the bytes

Page 14: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

15

• Return the input data in the given file as an array of strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getInput(String file, String splitter) {

URI uri = ClassLoader.getSystemResource(file).toURI();

String bytes = new String(Files.readAllBytes

(Paths.get(uri)));

return Pattern

.compile(splitter)

.splitAsStream(bytes)

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Compile a regular expression used to split the file into a list of strings

Page 15: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

16

• Return the input data in the given file as an array of strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getInput(String file, String splitter) {

URI uri = ClassLoader.getSystemResource(file).toURI();

String bytes = new String(Files.readAllBytes

(Paths.get(uri)));

return Pattern

.compile(splitter)

.splitAsStream(bytes)

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Filter out any empty strings in the stream

Page 16: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

17

• Return the input data in the given file as an array of strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getInput(String file, String splitter) {

URI uri = ClassLoader.getSystemResource(file).toURI();

String bytes = new String(Files.readAllBytes

(Paths.get(uri)));

return Pattern

.compile(splitter)

.splitAsStream(bytes)

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}Collect the results into a list of strings

Page 17: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

18

• Return the phrase list in the file as a list of non-empty strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getPhraseList(String file) {

return Files

.lines(Paths

.get(ClassLoader.getSystemResource(file).toURI()))

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Page 18: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

19

• Return the phrase list in the file as a list of non-empty strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getPhraseList(String file) {

return Files

.lines(Paths

.get(ClassLoader.getSystemResource(file).toURI()))

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Read all lines from file into a stream

Page 19: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

20

• Return the phrase list in the file as a list of non-empty strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getPhraseList(String file) {

return Files

.lines(Paths

.get(ClassLoader.getSystemResource(file).toURI()))

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Filter out any empty strings in the stream

Page 20: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

21

• Return the phrase list in the file as a list of non-empty strings

Example of Starting & Joining Java Threads with Java 8

static List<String> getPhraseList(String file) {

return Files

.lines(Paths

.get(ClassLoader.getSystemResource(file).toURI()))

.filter(((Predicate<String>) String::isEmpty).negate())

.collect(toList());

}

Collect the results into a list of strings

Page 21: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

22

• The main program creates & runs an instance of SearchOneShotThreadJoin

Example of Starting & Joining Java Threads with Java 8

public void main(String[] args) {

new SearchOneShotThreadJoin()

.run();

}

Create/run an object to search for all phrases in parallel

Page 22: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

23

• Several key Java 8 features

Example of Starting & Joining Java Threads with Java 8public void run() {

Start a group of threads that search for phrases in parallel

Page 23: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

24

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

Example of Starting & Joining Java Threads with Java 8public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

...

Factory method makes a list of worker threads

Page 24: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

25

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

Example of Starting & Joining Java Threads with Java 8public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

...

Void processInput(String input)

{ ... }

List<Thread> makeWorkerThreads

(Function<String, Void> task)

{ ... }

This method searches for phrases in one work of Shakespeare

Page 25: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

26

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

Example of Starting & Joining Java Threads with Java 8public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

...

This functional interface makes it easy to change function passed to factory method

Void processInput(String input)

{ ... }

List<Thread> makeWorkerThreads

(Function<String, Void> task)

{ ... }

Page 26: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

27

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Apply a function lambda to create runnable for a thread

Example of Starting & Joining Java Threads with Java 8List<Thread> makeWorkerThreads

(Function<String, Void> task) {

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}This factory method creates a

list of threads that will be joined when their processing is done

Page 27: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

28

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Apply a function lambda to create runnable for a thread

Example of Starting & Joining Java Threads with Java 8List<Thread> makeWorkerThreads

(Function<String, Void> task) {

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}Create an empty list of threads

Page 28: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

29

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Apply a function lambda to create runnable for a thread

Example of Starting & Joining Java Threads with Java 8List<Thread> makeWorkerThreads

(Function<String, Void> task) {

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}Create a thread for each input string to perform processing

designated by the task parameter

Page 29: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

30

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Apply a function lambda to create runnable for a thread

Example of Starting & Joining Java Threads with Java 8List<Thread> makeWorkerThreads

(Function<String, Void> task) {

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}task.apply() creates a runnable that provides the computation

for each of the threads

Page 30: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

31

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Apply a function lambda to create runnable for a thread

Example of Starting & Joining Java Threads with Java 8List<Thread> makeWorkerThreads

(Function<String, Void> task) {

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}

Add each new thread to the list

Page 31: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

32

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Apply a function lambda to create runnable for a thread

Example of Starting & Joining Java Threads with Java 8List<Thread> makeWorkerThreads

(Function<String, Void> task) {

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}

Return the list of worker threads

Page 32: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

33

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Start worker threads via forEach() & a method reference

Example of Starting & Joining Java Threads with Java 8public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

...

See docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

A Java thread is a unit of computation that runs in the context of a process

Page 33: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

34

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Start worker threads via forEach() & a method reference

Example of Starting & Joining Java Threads with Java 8public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

...

forEach() & method referencestart each worker thread to search

for phrases in works of shakespeare

Page 34: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

35

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Start worker threads via forEach() & a method reference

Example of Starting & Joining Java Threads with Java 8public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

...

This program uses a “thread-per-work” parallelism model

“MacBeth”“Hamlet”

“JuliusCaesar”

“KingLear”

Page 35: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

36

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Start worker threads via forEach() & a method reference

• Wait for worker threads to finish

Example of Starting & Joining Java Threads with Java 8

Uses forEach() & lambda expression

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(thread -> {

... thread.join(); ...

} ...

Page 36: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

37

Example of Starting & Joining Java Threads with Java 8

See en.wikipedia.org/wiki/Barrier_(computer_science)

• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Start worker threads via forEach() & a method reference

• Wait for worker threads to finish

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(thread -> {

... thread.join(); ...

} ...

Simple form of barrier synchronization

Page 37: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

38

Example of Starting & Joining Java Threads with Java 8• Several key Java 8 features, e.g.

• Flexibly create worker threads via a factory method

• Pass a reference to a method expecting a functional interface

• Start worker threads via forEach() & a method reference

• Wait for worker threads to finish

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(thread -> {

... thread.join(); ...

} ...

No other Java synchronizers are needed!

Page 38: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

39

Pros of the ThreadJoinTest Program

Page 39: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

40

Pros of the ThreadJoinTest Program• Using foundational Java 8 features

improves the program vis-à-vis original Java 7 version

See github.com/douglascraigschmidt/LiveLessons/tree/master/ThreadJoinTest/original

Starting ThreadJoinTestin thread 9 re was found at offset 1 in string xreoin thread 10 fa was found at offset 1 in string xfaoin thread 12 la was found at offset 1 in string xlaoin thread 13 ti was found at offset 1 in string xtiotioin thread 11 mi was found at offset 1 in string xmiomioin thread 11 mi was found at offset 4 in string xmiomioin thread 13 ti was found at offset 4 in string xtiotioin thread 14 so was found at offset 1 in string xsoosooin thread 14 so was found at offset 4 in string xsoosooin thread 16 do was found at offset 1 in string xdoodooin thread 16 do was found at offset 4 in string xdoodooin thread 16 do was found at offset 1 in string xdoodooin thread 16 do was found at offset 4 in string xdoodooin thread 15 do was found at offset 1 in string xdooin thread 15 do was found at offset 1 in string xdooEnding ThreadJoinTest

Page 40: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

41

Pros of the ThreadJoinTest Program• Using foundational Java 8 features

improves the program vis-à-vis original Java 7 version, e.g.

• The Java 7 version has additional syntax & traditional for loops

for (int i = 0;

i < mInput.size(); ++i) {

Thread t = new Thread

(makeTask(i));

mWorkerThreads.add(t);

}

...

Runnable makeTask(int i) {

return new Runnable() {

public void run() {

String e = mInput.get(i);

processInput(element);

}

...

Page 41: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

42

Pros of the ThreadJoinTest Program• Using foundational Java 8 features

improves the program vis-à-vis original Java 7 version, e.g.

• The Java 7 version has additional syntax & traditional for loops

for (int i = 0;

i < mInput.size(); ++i) {

Thread t = new Thread

(makeTask(i));

mWorkerThreads.add(t);

}

...

Runnable makeTask(int i) {

return new Runnable() {

public void run() {

String e = mInput.get(i);

processInput(element);

}

...

The Java 7 version is thus more tedious & error-prone to program..

Page 42: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

43

Pros of the ThreadJoinTest Program• Using foundational Java 8 features

improves the program vis-à-vis original Java 7 version, e.g.

• The Java 7 version has additional syntax & traditional for loops

• The Java 8 implementation is a bit more concise & extensible

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

...

List<Thread> makeWorkerThreads

(Function<String, Void> task) {

...

mInputList.forEach(input ->

workerThreads.add

(new Thread(() -> task.apply(input))));

e.g., declarative Java 8 features such as forEach(), functional

interfaces, method references, & lambda expressions

Page 43: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

44

Cons of the ThreadJoinTest Program

Page 44: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

45

Cons of the ThreadJoinTest Program• There’s still “accidental complexity”

in the Java 8 version

See en.wikipedia.org/wiki/No_Silver_Bullet

Accidental complexities arise from limitations with software techniques, tools, & methods

Page 45: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

46

Cons of the ThreadJoinTest Program• There’s still “accidental complexity”

in the Java 8 version, e.g.

• Manually creating, starting, &joining threads

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(thread -> {

try { thread.join(); }

catch(Exception e) {

throw new

RuntimeException(e);

}}); ...

You must remember to start each thread!

Page 46: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

47

Cons of the ThreadJoinTest Program• There’s still “accidental complexity”

in the Java 8 version, e.g.

• Manually creating, starting, &joining threads

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(thread -> {

try { thread.join(); }

catch(Exception e) {

throw new

RuntimeException(e);

}}); ...

Note the verbosity of handling checked exceptions in Java 8 programs..

See codingjunkie.net/functional-iterface-exceptions

Page 47: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

48

Cons of the ThreadJoinTest Program• There’s still “accidental complexity”

in the Java 8 version, e.g.

• Manually creating, starting, &joining threads

public void run() {

List<Thread> workerThreads =

makeWorkerThreads

(this::processInput);

workerThreads

.forEach(Thread::start);

workerThreads

.forEach(ExceptionUtils

.rethrowConsumer

(Thread::join));

A helper class enables less verbosely use of checked exceptions in Java 8 programs

See stackoverflow.com/a/27644392/3312330

Page 48: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

49

Cons of the ThreadJoinTest Program• There’s still “accidental complexity”

in the Java 8 version, e.g.

• Manually creating, starting, &joining threads

• Only one parallelism model supported

• “thread-per-work” hard-codes the# of threads to # of input strings

List<Thread> makeWorkerThreads

(Function<String, Void> task){

List<Thread> workerThreads =

new ArrayList<>();

mInputList.forEach(input ->

workerThreads.add

(new Thread(()

-> task.apply(input))));

return workerThreads;

}

Page 49: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

50

Cons of the ThreadJoinTest Program• There’s still “accidental complexity”

in the Java 8 version, e.g.

• Manually creating, starting, &joining threads

• Only one parallelism model supported

• Not easily extensible withoutmajor changes to the code

• e.g., insufficiently declarative

Page 50: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

51

Cons of the ThreadJoinTest Program• Solving these problems requires more than the foundational Java 8 features

See www.dre.vanderbilt.edu/~schmidt/DigitalLearning

Page 51: Applying Java 8 Functional Programming Features to a ... · •Understand how Java 8 functional programming features are applied in a simple parallel program •This program searches

52

End of Applying Java 8 Functional Programming

Features to a Parallel Program