99
. . . . . . Concurrency in the Java Language and Platform Fredrik Öhrström Principal Member of Technical Staff JRockit+Hotspot

Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

Embed Size (px)

DESCRIPTION

2011-11-02 | 10:00 AM - 11:00 AM | VictoriaOracle has initiated a renewal of Java and one of the more important goals is to make it easier to write concurrent software that makes use of all cores in modern hardware. This will require changes both to the language Java as well as its virtual machine. I will describe the latest design that we are working on and demonstrate what can be achieved today using the JRockit JVM and how we can improve concurrency in javac itself.

Citation preview

Page 1: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Concurrency in the Java Language and Platform

Fredrik ÖhrströmPrincipal Member of Technical Staff

JRockit+Hotspot

I have worked on the JRockit JVM for the last 6 six years and onthe OpenJDK during the last year.

Thus I am bi-jvm-lingual.I am now working in the language team led

by the Java Language Architect Brian Goetz.Though I am currently sidetracked to rewrite the build system for

OpenJDK.

Page 2: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Concurrency in the Java Language and Platform

Fredrik ÖhrströmPrincipal Member of Technical Staff

JRockit+Hotspot

I have worked on the JRockit JVM for the last 6 six years and onthe OpenJDK during the last year.

Thus I am bi-jvm-lingual.I am now working in the language team led

by the Java Language Architect Brian Goetz.Though I am currently sidetracked to rewrite the build system for

OpenJDK.

Page 3: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

The following is intended to outline our general product direction.It is intended for information purposes only, and may not beincorporated into any contract. It is not a commitment to deliverany material, code, or functionality, and should not be relied uponin making purchasing decisions. The development, release, andtiming of any features or functionality described for Oracle’sproducts remains at the sole discretion of Oracle.

Page 4: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In the beginning

I In 1974, Donald Knuth wrote a paper with the titleStructured Programming with goto statements.

I “In the late 1960s we witnessed a ’software crisis,’ whichmany people thought paradoxical because programming wassupposed to be easy.”

I It then takes him approx 60 pages to discuss the problemswith for-loops that were relevant at the time.

I Today, it is even more complicated!

Page 5: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In the beginning

I In 1974, Donald Knuth wrote a paper with the titleStructured Programming with goto statements.

I “In the late 1960s we witnessed a ’software crisis,’ whichmany people thought paradoxical because programming wassupposed to be easy.”

I It then takes him approx 60 pages to discuss the problemswith for-loops that were relevant at the time.

I Today, it is even more complicated!

Page 6: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In the beginning

I In 1974, Donald Knuth wrote a paper with the titleStructured Programming with goto statements.

I “In the late 1960s we witnessed a ’software crisis,’ whichmany people thought paradoxical because programming wassupposed to be easy.”

I It then takes him approx 60 pages to discuss the problemswith for-loops that were relevant at the time.

I Today, it is even more complicated!

Page 7: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In the beginning

I In 1974, Donald Knuth wrote a paper with the titleStructured Programming with goto statements.

I “In the late 1960s we witnessed a ’software crisis,’ whichmany people thought paradoxical because programming wassupposed to be easy.”

I It then takes him approx 60 pages to discuss the problemswith for-loops that were relevant at the time.

I Today, it is even more complicated!

Page 8: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore = 0.0;for (Student s : students) {if (s.gradYear == 2010) {

if (s.score > highestScore) {highestScore = s.score;

}}

}

I Traversal logic is encoded into bytecode.I Business logic is stateful.I Existing collections impose external iterationI For complex datasets the iterator becomes unnecessary

complex.

Page 9: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore = 0.0;for (Student s : students) {if (s.gradYear == 2010) {

if (s.score > highestScore) {highestScore = s.score;

}}

}

I Traversal logic is encoded into bytecode.

I Business logic is stateful.I Existing collections impose external iterationI For complex datasets the iterator becomes unnecessary

complex.

Page 10: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore = 0.0;for (Student s : students) {if (s.gradYear == 2010) {

if (s.score > highestScore) {highestScore = s.score;

}}

}

I Traversal logic is encoded into bytecode.I Business logic is stateful.

I Existing collections impose external iterationI For complex datasets the iterator becomes unnecessary

complex.

Page 11: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore = 0.0;for (Student s : students) {if (s.gradYear == 2010) {

if (s.score > highestScore) {highestScore = s.score;

}}

}

I Traversal logic is encoded into bytecode.I Business logic is stateful.I Existing collections impose external iteration

I For complex datasets the iterator becomes unnecessarycomplex.

Page 12: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore = 0.0;for (Student s : students) {if (s.gradYear == 2010) {

if (s.score > highestScore) {highestScore = s.score;

}}

}

I Traversal logic is encoded into bytecode.I Business logic is stateful.I Existing collections impose external iterationI For complex datasets the iterator becomes unnecessary

complex.

Page 13: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

This might sound like a theoretical exercise, but Oracle is affectedby the lack of concurrency in Javac, right at this very moment.

Page 14: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 15: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 16: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 17: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 18: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 19: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Developers need easy to use parallel libraries

I One of Java’s strengths has always been its librariesI Ideally the library should decide which strategy to use to

decompose the problem into parallel parts.I Obvious places are the collection classes, add parallel: filter,

sort, map/reduce, select, collect, detect, reject

I Why don’t we see more parallel libraries today?

Page 20: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Developers need easy to use parallel libraries

I One of Java’s strengths has always been its librariesI Ideally the library should decide which strategy to use to

decompose the problem into parallel parts.I Obvious places are the collection classes, add parallel: filter,

sort, map/reduce, select, collect, detect, rejectI Why don’t we see more parallel libraries today?

Page 21: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Without more language support forparallel idioms, people willinstinctively reach for serial idioms.

Page 22: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Internal iteration (functional approach)double highestScore =students.filter(new Predicate<Student>() {

public boolean op(Student s) {return s.gradYear == 2010;

}}).map(new Extractor<Student,Double>() {

public Double extract(Student s) {return s.score;

}}).max();

I Not inherently serial.I Traversal logic completely inside collection.I Stateless!I Can be done in parallel!

Page 23: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Internal iteration (functional approach)double highestScore =students.filter(new Predicate<Student>() {

public boolean op(Student s) {return s.gradYear == 2010;

}}).map(new Extractor<Student,Double>() {

public Double extract(Student s) {return s.score;

}}).max();

I Not inherently serial.

I Traversal logic completely inside collection.I Stateless!I Can be done in parallel!

Page 24: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Internal iteration (functional approach)double highestScore =students.filter(new Predicate<Student>() {

public boolean op(Student s) {return s.gradYear == 2010;

}}).map(new Extractor<Student,Double>() {

public Double extract(Student s) {return s.score;

}}).max();

I Not inherently serial.I Traversal logic completely inside collection.

I Stateless!I Can be done in parallel!

Page 25: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Internal iteration (functional approach)double highestScore =students.filter(new Predicate<Student>() {

public boolean op(Student s) {return s.gradYear == 2010;

}}).map(new Extractor<Student,Double>() {

public Double extract(Student s) {return s.score;

}}).max();

I Not inherently serial.I Traversal logic completely inside collection.I Stateless!

I Can be done in parallel!

Page 26: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Internal iteration (functional approach)double highestScore =students.filter(new Predicate<Student>() {

public boolean op(Student s) {return s.gradYear == 2010;

}}).map(new Extractor<Student,Double>() {

public Double extract(Student s) {return s.score;

}}).max();

I Not inherently serial.I Traversal logic completely inside collection.I Stateless!I Can be done in parallel!

Page 27: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

The noise, the noisedouble highestScore =students.filter(new Predicate<Student>() {

public boolean op(Student s) {return s.gradYear == 2010;

}}).map(new Extractor<Student,Double>() {

public Double extract(Student s) {return s.score;

}}).max();

I Not inherently serial.I Traversal logic completely inside collection.I Stateless!I Can be done in parallel!

Page 28: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

Page 29: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I An -> identifies a lambda expressionI Target type parametersI More than one parameter (a,b)->cI Body may be an expression or {statements}

Page 30: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I An -> identifies a lambda expression

I Target type parametersI More than one parameter (a,b)->cI Body may be an expression or {statements}

Page 31: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I An -> identifies a lambda expressionI Target type parameters

I More than one parameter (a,b)->cI Body may be an expression or {statements}

Page 32: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I An -> identifies a lambda expressionI Target type parametersI More than one parameter (a,b)->c

I Body may be an expression or {statements}

Page 33: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I An -> identifies a lambda expressionI Target type parametersI More than one parameter (a,b)->cI Body may be an expression or {statements}

Page 34: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I Code reads like the problem statement: Find the highest scoreof the students who graduated in 2010”

I Shorter than nested for loops, and potentially faster becausethe collection implementation determines how to iterate

I filter() method body can exploit representation knowledgeI Opportunities for lazy evaluation in filter() and map()I Opportunities for parallelism

Page 35: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I Code reads like the problem statement: Find the highest scoreof the students who graduated in 2010”

I Shorter than nested for loops, and potentially faster becausethe collection implementation determines how to iterate

I filter() method body can exploit representation knowledgeI Opportunities for lazy evaluation in filter() and map()I Opportunities for parallelism

Page 36: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I Code reads like the problem statement: Find the highest scoreof the students who graduated in 2010”

I Shorter than nested for loops, and potentially faster becausethe collection implementation determines how to iterate

I filter() method body can exploit representation knowledge

I Opportunities for lazy evaluation in filter() and map()I Opportunities for parallelism

Page 37: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I Code reads like the problem statement: Find the highest scoreof the students who graduated in 2010”

I Shorter than nested for loops, and potentially faster becausethe collection implementation determines how to iterate

I filter() method body can exploit representation knowledgeI Opportunities for lazy evaluation in filter() and map()

I Opportunities for parallelism

Page 38: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Code as data?

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

I Code reads like the problem statement: Find the highest scoreof the students who graduated in 2010”

I Shorter than nested for loops, and potentially faster becausethe collection implementation determines how to iterate

I filter() method body can exploit representation knowledgeI Opportunities for lazy evaluation in filter() and map()I Opportunities for parallelism

Page 39: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

I The name comes from the lambda calculus created by Church(1936)

I Later explored by Steele and Sussman (1975-1980)I Thus by adding lambda expressions we have moved from 1974

(Knuth’s structured gotos) to 1975 (Scheme and lexicallambdas).

I Yay!

Page 40: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

I The name comes from the lambda calculus created by Church(1936)

I Later explored by Steele and Sussman (1975-1980)

I Thus by adding lambda expressions we have moved from 1974(Knuth’s structured gotos) to 1975 (Scheme and lexicallambdas).

I Yay!

Page 41: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

I The name comes from the lambda calculus created by Church(1936)

I Later explored by Steele and Sussman (1975-1980)I Thus by adding lambda expressions we have moved from 1974

(Knuth’s structured gotos) to 1975 (Scheme and lexicallambdas).

I Yay!

Page 42: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

I The name comes from the lambda calculus created by Church(1936)

I Later explored by Steele and Sussman (1975-1980)I Thus by adding lambda expressions we have moved from 1974

(Knuth’s structured gotos) to 1975 (Scheme and lexicallambdas).

I Yay!

Page 43: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

I A lambda expression is a lexically scoped anonymous method.

I Lexical scoping: can read variables from the lexicalenvironment, including “this”, unlike inner classes.

I No shadowing of lexical scope, unlike inner classes.I Not a member of any class, unlike inner classes.

Page 44: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Lambda Expressions

I A lambda expression is a lexically scoped anonymous method.I Lexical scoping: can read variables from the lexical

environment, including “this”, unlike inner classes.I No shadowing of lexical scope, unlike inner classes.I Not a member of any class, unlike inner classes.

Page 45: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Why were lambda expressions not added earlier to Java?

I After all, Steele who wrote the lambda papers in 1975, workedin the Java team for several years!

I The reason was the design decision that every memoryallocation should be visible as a “new” in Java source code.

I And the reason for this decision was that the hardware of thetime simply was not powerful enough.

I But now we have enough hardware to be able to spendsignificant cpu power on the optimization problems and GC tomake this less of a problem.

Page 46: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Why were lambda expressions not added earlier to Java?

I After all, Steele who wrote the lambda papers in 1975, workedin the Java team for several years!

I The reason was the design decision that every memoryallocation should be visible as a “new” in Java source code.

I And the reason for this decision was that the hardware of thetime simply was not powerful enough.

I But now we have enough hardware to be able to spendsignificant cpu power on the optimization problems and GC tomake this less of a problem.

Page 47: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Why were lambda expressions not added earlier to Java?

I After all, Steele who wrote the lambda papers in 1975, workedin the Java team for several years!

I The reason was the design decision that every memoryallocation should be visible as a “new” in Java source code.

I And the reason for this decision was that the hardware of thetime simply was not powerful enough.

I But now we have enough hardware to be able to spendsignificant cpu power on the optimization problems and GC tomake this less of a problem.

Page 48: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Why were lambda expressions not added earlier to Java?

I After all, Steele who wrote the lambda papers in 1975, workedin the Java team for several years!

I The reason was the design decision that every memoryallocation should be visible as a “new” in Java source code.

I And the reason for this decision was that the hardware of thetime simply was not powerful enough.

I But now we have enough hardware to be able to spendsignificant cpu power on the optimization problems and GC tomake this less of a problem.

Page 49: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Why were lambda expressions not added earlier to Java?

I After all, Steele who wrote the lambda papers in 1975, workedin the Java team for several years!

I The reason was the design decision that every memoryallocation should be visible as a “new” in Java source code.

I And the reason for this decision was that the hardware of thetime simply was not powerful enough.

I But now we have enough hardware to be able to spendsignificant cpu power on the optimization problems and GC tomake this less of a problem.

Page 50: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Typing

Page 51: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

What is the type of a lambda expression?

s -> s.gradYear == 2010

I Morally, a function type from Student to booleanI But Java does not have function types....

Page 52: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

What is the type of a lambda expression?

s -> s.gradYear == 2010

I How would we write a function type?I How would it interact with boxing?I How would it interact with generics?I How would it describe checked exceptions?I Would it be possible to overload based on function type?

Page 53: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In Java we use interfaces (and abstract classes) in two differentways:

I To specify behaviour: PrintWriter.println(),Student.setGrade(), GraphicsObject.render().

I To specify calling parameters and return value:Runnable.run(), Callable.call(), Comparator.compare(),ActionListener.actionPerformed(),TimerTask.run()

We can reuse the second kind of interfaces as function types. Forbackwards compatibility. When we have reified Java, then we canmore easily add real function types.

Page 54: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In Java we use interfaces (and abstract classes) in two differentways:

I To specify behaviour: PrintWriter.println(),Student.setGrade(), GraphicsObject.render().

I To specify calling parameters and return value:Runnable.run(), Callable.call(), Comparator.compare(),ActionListener.actionPerformed(),TimerTask.run()

We can reuse the second kind of interfaces as function types. Forbackwards compatibility. When we have reified Java, then we canmore easily add real function types.

Page 55: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In Java we use interfaces (and abstract classes) in two differentways:

I To specify behaviour: PrintWriter.println(),Student.setGrade(), GraphicsObject.render().

I To specify calling parameters and return value:Runnable.run(), Callable.call(), Comparator.compare(),ActionListener.actionPerformed(),TimerTask.run()

We can reuse the second kind of interfaces as function types. Forbackwards compatibility. When we have reified Java, then we canmore easily add real function types.

Page 56: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

In Java we use interfaces (and abstract classes) in two differentways:

I To specify behaviour: PrintWriter.println(),Student.setGrade(), GraphicsObject.render().

I To specify calling parameters and return value:Runnable.run(), Callable.call(), Comparator.compare(),ActionListener.actionPerformed(),TimerTask.run()

We can reuse the second kind of interfaces as function types. Forbackwards compatibility. When we have reified Java, then we canmore easily add real function types.

Page 57: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Introducing SAM-types

A SAM-type is an interface or abstract class with a Single AbstractMethod

interface Runnable { void run(); }interface Callable<T> { T call(); }interface Comparator<T> { boolean compare(T x, T y); }interface ActionListener { void actionPerformed(...);abstract class TimerTask { ... abstract void run(); ... }

Page 58: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

The type of a lambda expression is a SAM-type

“SAM-conversion” infers a SAM-type for a lambda expression:

Predicate<Student> p = s -> s.gradYear == 2010;

Invoking the SAM-type’s method invokes the lambdas’s body

boolean ok = p.isTrue(aStudent);

Instant compatibility with existing libraries!

executor.submit( ()->{ println(“Boo”); });

Lambda expressions may only appear in contexts where they canundergo SAM conversion (assignment, method call/return, cast).

Page 59: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

The type of a lambda expression is a SAM-type

“SAM-conversion” infers a SAM-type for a lambda expression:

Predicate<Student> p = s -> s.gradYear == 2010;

Invoking the SAM-type’s method invokes the lambdas’s body

boolean ok = p.isTrue(aStudent);

Instant compatibility with existing libraries!

executor.submit( ()->{ println(“Boo”); });

Lambda expressions may only appear in contexts where they canundergo SAM conversion (assignment, method call/return, cast).

Page 60: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore =students.filter( (Student s)-> s.gradYear == 2010).map((Student s)-> s.score).max();

Since SAM-conversion uses target typing, the parameter types canbe left out!

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

Page 61: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

double highestScore =students.filter( (Student s)-> s.gradYear == 2010).map((Student s)-> s.score).max();

Since SAM-conversion uses target typing, the parameter types canbe left out!

double highestScore =students.filter(s -> s.gradYear == 2010).map(s -> s.score).max();

Page 62: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

So, lambda expressions are just a better syntax for inneranonymous classes? I.e. more sugar?

No! They cannot be!To understand why, we need to understand how the JVM achieveshigh performance today.

Page 63: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

So, lambda expressions are just a better syntax for inneranonymous classes? I.e. more sugar?

No! They cannot be!

To understand why, we need to understand how the JVM achieveshigh performance today.

Page 64: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

So, lambda expressions are just a better syntax for inneranonymous classes? I.e. more sugar?

No! They cannot be!To understand why, we need to understand how the JVM achieveshigh performance today.

Page 65: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

static class Coord {final int x, y;

Coord(int xx, int yy) { x=xx; y=yy; }Coord add(Coord c) {

return new Coord(x+c.x,y+c.y);}double dist(Coord c) {

int dx = c.x-x;int dy = c.y-y;return Math.sqrt(dx*dx+dy*dy);

}}

Page 66: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

public static class Matrix {int a,b,c,d;

public Matrix(int aa, int bb, int cc, int dd) {a = aa; b = bb; c = cc; d = dd;

}public static Matrix scaler(int k) {

return new Matrix(k,0,0,k);}public Matrix mul(int k) {

return new Matrix(a*k,b*k,c*k,d*k);}Coord mul(Coord co) {

return new Coord(co.x*a+co.y*c,co.x*b+co.y*d);}

}

Page 67: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Calculation

[33 00 33

]× 2×

[kk

]−

[2211

]=

[dxdy

]

answer =√

dx2 + dy2

public static double test(int k) {return Matrix.scaler(33).mul(2).mul(new Coord(k,k))

.dist(new Coord(22,11));}

Page 68: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Calculation

[33 00 33

]× 2×

[kk

]−

[2211

]=

[dxdy

]

answer =√

dx2 + dy2

public static double test(int k) {return Matrix.scaler(33).mul(2).mul(new Coord(k,k))

.dist(new Coord(22,11));}

Page 69: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Calculation

public static void main(String... args) {int i=0;double d = 0;for (;;) {

d = test(4711);if (++i > 1000000) {System.out.println("+d);i=0;

}}

}

Page 70: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 71: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

x86_sub esp ← esp 4x86_mov edi ← eaxx86_test *[0xb722f000] eaxx86_imul eax ← eax 66x86_imul edi ← edi 66x86_mov ecx ← 22x86_sub ecx ← ecx eaxx86_mov esi ← 11x86_sub esi ← esi edix86_imul ecx ← ecx ecxx86_imul esi ← esi esix86_add ecx ← ecx esix86_cvtsi2sd xmm0 ← ecxx86_sqrtsd xmm0 ← xmm0x86_pop ecx esp ← espx86_retxmm0 esp

Page 72: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Inlining implies great optimization opportunities

Page 73: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

But where to inline when using multiple cores?

Page 74: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Page 75: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Fortunately a new JVM technology called the MethodHandleis available for us.

I A MethodHandle is (among many things) a root for inliningthat require no function!

I A MethodHandle will be hidden behind the SAM-typeinterface.

I It can express new code using objects on the Java heap.

I This code can be efficiently optimized.

Page 76: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Fortunately a new JVM technology called the MethodHandleis available for us.

I A MethodHandle is (among many things) a root for inliningthat require no function!

I A MethodHandle will be hidden behind the SAM-typeinterface.

I It can express new code using objects on the Java heap.I This code can be efficiently optimized.

Page 77: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Assume an interface to extract a value from an object:

interface Extractor<T, U> { U get(T element); }

And a new sort method on Collections using the Extractor:

public <T, U extends Comparable<...>>void sortBy(Collection<T> coll, Extractor<T,U> ex) {...}

Then, pass a lambda expression that “wraps” a method call:

Collections.sortBy(people, p -> p.getLastName() );

I SAM conversion types the lambda asExtractor<Person,String>

I sortBy() can pre-query last names, cache them, build indices...

Page 78: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Is that the best we can do?

Collections.sortBy(people, p -> p.getLastName() );

Writing little wrapper lambdas will be a pain!Lets reference a method directly!

Collections.sortBy(people, Person#getLastName );

I Method reference introduced with # (not locked down yet!)I No need for () or parameter types in simple cases

Page 79: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Another very common use case!

To bind user interface callbacks to your code:save_button.addActionListener(this#save);

Or even shorter:save_button.addActionListener(#save);

Page 80: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Another very common use case!

To bind user interface callbacks to your code:save_button.addActionListener(this#save);Or even shorter:save_button.addActionListener(#save);

Page 81: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Recap

I When code outgrows a lambda expression, write a methodand take a method reference

I Lambda expressions and method references have SAM typesI Work easily with existing librariesI Can specify parameter types explicitly if neededI Three kinds of method references (unbound/bound/static)I No field references (use method references to getters/setters)

Page 82: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Wrap up

Page 83: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Collections.sort(people, new Comparator<Person>() {public int compare(Person x, Person y) {return x.getLastName().compareTo(y.getLastName());

}});

Collections.sort(people, (Person x, Person y)->x.getLastName().compareTo(y.getLastName()) );

Collections.sortBy(people, (Person p)-> p.getLastName() );

Collections.sortBy(people, p -> p.getLastName() );

Collections.sortBy(people, Person#getLastName);

Page 84: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Collections.sort(people, new Comparator<Person>() {public int compare(Person x, Person y) {return x.getLastName().compareTo(y.getLastName());

}});

Collections.sort(people, (Person x, Person y)->x.getLastName().compareTo(y.getLastName()) );

Collections.sortBy(people, (Person p)-> p.getLastName() );

Collections.sortBy(people, p -> p.getLastName() );

Collections.sortBy(people, Person#getLastName);

Page 85: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Collections.sort(people, new Comparator<Person>() {public int compare(Person x, Person y) {return x.getLastName().compareTo(y.getLastName());

}});

Collections.sort(people, (Person x, Person y)->x.getLastName().compareTo(y.getLastName()) );

Collections.sortBy(people, (Person p)-> p.getLastName() );

Collections.sortBy(people, p -> p.getLastName() );

Collections.sortBy(people, Person#getLastName);

Page 86: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Collections.sort(people, new Comparator<Person>() {public int compare(Person x, Person y) {return x.getLastName().compareTo(y.getLastName());

}});

Collections.sort(people, (Person x, Person y)->x.getLastName().compareTo(y.getLastName()) );

Collections.sortBy(people, (Person p)-> p.getLastName() );

Collections.sortBy(people, p -> p.getLastName() );

Collections.sortBy(people, Person#getLastName);

Page 87: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Collections.sort(people, new Comparator<Person>() {public int compare(Person x, Person y) {return x.getLastName().compareTo(y.getLastName());

}});

Collections.sort(people, (Person x, Person y)->x.getLastName().compareTo(y.getLastName()) );

Collections.sortBy(people, (Person p)-> p.getLastName() );

Collections.sortBy(people, p -> p.getLastName() );

Collections.sortBy(people, Person#getLastName);

Page 88: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference - Less ceremonyI Method references - More reuseI JVM support - More performance

Page 89: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions

- More conciseI Better libraries - More abstractI Type inference - Less ceremonyI Method references - More reuseI JVM support - More performance

Page 90: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More concise

I Better libraries - More abstractI Type inference - Less ceremonyI Method references - More reuseI JVM support - More performance

Page 91: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries

- More abstractI Type inference - Less ceremonyI Method references - More reuseI JVM support - More performance

Page 92: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstract

I Type inference - Less ceremonyI Method references - More reuseI JVM support - More performance

Page 93: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference

- Less ceremonyI Method references - More reuseI JVM support - More performance

Page 94: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference - Less ceremony

I Method references - More reuseI JVM support - More performance

Page 95: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference - Less ceremonyI Method references

- More reuseI JVM support - More performance

Page 96: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference - Less ceremonyI Method references - More reuse

I JVM support - More performance

Page 97: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference - Less ceremonyI Method references - More reuseI JVM support

- More performance

Page 98: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

I Lambda expressions - More conciseI Better libraries - More abstractI Type inference - Less ceremonyI Method references - More reuseI JVM support - More performance

Page 99: Java Core | Concurrency in the Java Language and Platform | Fredrik Ohrstrom

. . . . . .

Thanks!