Top Banner
cocktail d’expérience informatiques Genève 3 & 4 octobre 2011 Seconde édition Track Auteur Session Java Julien PONGE Java SE 7 soft -shake.ch
77

soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

May 20, 2015

Download

Technology

soft-shake.ch

Julien Ponge


This talk introduces part of the Java SE 7 novelties. The fork/join framework aims at making parallel programming simpler, while Project Coin brings a set of subtle yet useful changes to the Java programming language.


http://soft-shake.ch/2011/conference/sessions/java/2011/09/06/java7.html
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

cocktail d’expérience informatiquesGenève 3 & 4 octobre 2011

Seconde édition

Track

Auteur

Session

Java

Julien PONGE

Java SE 7

soft-shake.ch

Page 2: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
Page 3: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Java SE 7Julien Ponge

Page 4: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
Page 5: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Fork / Join

Project Coin

NIO.2

invokedynamic

(...)

Page 6: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Fork / Join

Page 7: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

synchronized

wait()notify()< 5

java.lang.Threadjava.lang.Runnable

Page 8: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Thread thread = new Thread() { public void run() { System.out.println(">>> Hello!"); }}; thread.start();thread.join();

Page 9: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

java.util.concurrent

executorsconcurrent queuesconcurrent collectionsatomic variablessynchronization patternsrich locks

5, 6

Page 10: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

class Sum implements Callable<Long> { private final long from; private final long to; Sum(long from, long to) { this.from = from; this.to = to; } public Long call() { long acc = 0; for (long i = from; i <= to; i++) { acc = acc + i; } return acc; } }

Page 11: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

ExecutorService executor = Executors.newFixedThreadPool(2);

List<Future<Long>> results = executor.invokeAll(asList( new Sum(0, 10), new Sum(100, 1000), new Sum(10000, 1000000)));

for (Future<Long> result : results) { System.out.println(result.get());}

Page 12: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Threads made easy

Concurrency made easier

Parallelism made easier

1.01.11.21.31.4

56

7

Page 13: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

n1 n2 n3 n4 n5 n6 n8n7 n9 ... ... ......

sum1 sum2 sum3sum1 + sum2 sum3 + (...)

total sum

Sum of an array

Page 14: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

How many occurrences of “java.util.List” in this filesystem tree?

Page 15: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Load into RAM (1 thread)

subfolders: List<Folder>documents: List<Document>

Folderlines: List<String>

Document

Divide & conquer (#cores threads)

Page 16: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

SplitFork subtasksJoin subtasksCompose results

Thread managementMaximize parallelism

Work stealing

Your workForkJoinPool

Page 17: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Child ForkJoinTask

fork() fork()join() join()

Child ForkJoinTask

ForkJoinTask

RecursiveActionvs

RecursiveTask

Page 18: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Document wordcounting task

Document wordcounting task

Folder wordcounting task

Folder wordcounting task

Document wordcounting task

Document wordcounting task

3

n

2

51

10

16

fork()

join()

Page 19: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

(F/J demo)

Page 20: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

1"

2"

3"

4"

5"

6"

7"

2" 4" 6" 8" 10" 12"

Speedup&

#cores

Page 21: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

No I/ONo synchronization / locks

Decompose in simple recursive tasksDo not decompose below a threshold

Take advantage of multicores with no pain

You have more F/J candidate algorithms than you think!

Page 22: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try-with-resources

Page 23: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private void writeSomeData() throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close();}

Page 24: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private void writeSomeData() throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close();}

what if...

Page 25: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private void writeSomeData() throws IOException { DataOutputStream out = null; try { out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); } finally { if (out != null) { out.close(); } } }

Page 26: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private void writeSomeData() throws IOException { DataOutputStream out = null; try { out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); } finally { if (out != null) { out.close(); } } }

...this is still far from correct!

Page 27: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try (

FileOutputStream out = new FileOutputStream("output"); FileInputStream in1 = new FileInputStream(“input1”); FileInputStream in2 = new FileInputStream(“input2”)

) {

// Do something useful with those 3 streams! // out, in1 and in2 will be closed in any case

out.write(in1.read()); out.write(in2.read());}

Page 28: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

public class AutoClose implements AutoCloseable { @Override public void close() { System.out.println(">>> close()"); throw new RuntimeException("Exception in close()"); } public void work() throws MyException { System.out.println(">>> work()"); throw new MyException("Exception in work()"); }}

Page 29: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}

Page 30: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}

>>> work() >>> close() java.lang.RuntimeException: Exception in close()        at AutoClose.close(AutoClose.java:6)        at AutoClose.runWithMasking(AutoClose.java:19)        at AutoClose.main(AutoClose.java:52)

Page 31: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}

>>> work() >>> close() java.lang.RuntimeException: Exception in close()        at AutoClose.close(AutoClose.java:6)        at AutoClose.runWithMasking(AutoClose.java:19)        at AutoClose.main(AutoClose.java:52)

MyException masked by RuntimeException

Page 32: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

“Caused by” ≠ “Also happened”

Page 33: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 34: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 35: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 36: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 37: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 38: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try (AutoClose autoClose = new AutoClose()) { autoClose.work();}

Page 39: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try (AutoClose autoClose = new AutoClose()) { autoClose.work();}

>>> work() >>> close() MyException: Exception in work()        at AutoClose.work(AutoClose.java:11)        at AutoClose.main(AutoClose.java:16)        Suppressed: java.lang.RuntimeException: Exception in close()               at AutoClose.close(AutoClose.java:6)               at AutoClose.main(AutoClose.java:17)

Page 40: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

public void compress(String input, String output) throws IOException { try( FileInputStream fin = new FileInputStream(input); FileOutputStream fout = new FileOutputStream(output); GZIPOutputStream out = new GZIPOutputStream(fout) ) { byte[] buffer = new byte[4096]; int nread = 0; while ((nread = fin.read(buffer)) != -1) { out.write(buffer, 0, nread); } }}

Page 41: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

public void compress(String paramString1, String paramString2)         throws IOException {     FileInputStream localFileInputStream = new FileInputStream(paramString1);    Object localObject1 = null;     try {         FileOutputStream localFileOutputStream = new FileOutputStream(paramString2);        Object localObject2 = null;         try {             GZIPOutputStream localGZIPOutputStream = new GZIPOutputStream(localFileOutputStream);            Object localObject3 = null;             try {                 byte[] arrayOfByte = new byte[4096];                 int i = 0;                 while ((i = localFileInputStream.read(arrayOfByte)) != -1) {                     localGZIPOutputStream.write(arrayOfByte, 0, i);                 }             } catch (Throwable localThrowable6) {                 localObject3 = localThrowable6;                 throw localThrowable6;             } finally {                 if (localGZIPOutputStream != null) {                     if (localObject3 != null) {                         try {                             localGZIPOutputStream.close();                         } catch (Throwable localThrowable7) {                             localObject3.addSuppressed(localThrowable7);                         }                     } else {                         localGZIPOutputStream.close();                     }                 }             }         } catch (Throwable localThrowable4) {             localObject2 = localThrowable4;             throw localThrowable4;         } finally {             if (localFileOutputStream != null) {                 if (localObject2 != null) {                     try {                         localFileOutputStream.close();                     } catch (Throwable localThrowable8) {                         localObject2.addSuppressed(localThrowable8);                     }                 } else {                     localFileOutputStream.close();                 }             }         }     } catch (Throwable localThrowable2) {         localObject1 = localThrowable2;         throw localThrowable2;     } finally {         if (localFileInputStream != null) {             if (localObject1 != null) {                 try {                     localFileInputStream.close();                 } catch (Throwable localThrowable9) {                     localObject1.addSuppressed(localThrowable9);                 }             } else {                 localFileInputStream.close();             }         }     } }

public void compress(String input, String output) throws IOException { try( FileInputStream fin = new FileInputStream(input); FileOutputStream fout = new FileOutputStream(output); GZIPOutputStream out = new GZIPOutputStream(fout) ) { byte[] buffer = new byte[4096]; int nread = 0; while ((nread = fin.read(buffer)) != -1) { out.write(buffer, 0, nread); } }}

Page 42: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Not just syntactic sugarClutter-free, correct code

close(): - be more specific than java.lang.Exception - no exception if it can’t fail - no exception that shall not be suppressed (e.g., java.lang.InterruptedException)

Page 43: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Diamond <>

Page 44: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

List<String> strings = new LinkedList<Integer>();

Map<String, List<String>> contacts = new HashMap<Integer, String>();

Page 45: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

List<String> strings = new LinkedList<String>();strings.add("hello");strings.add("world");

Map<String, List<String>> contacts = new HashMap<String, List<String>>();contacts.put("Julien", new LinkedList<String>());contacts.get("Julien").addAll(asList("Foo", "Bar", "Baz"));

Page 46: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

List<String> strings = new LinkedList<>();strings.add("hello");strings.add("world");

Map<String, List<String>> contacts = new HashMap<>();contacts.put("Julien", new LinkedList<String>());contacts.get("Julien").addAll(asList("Foo", "Bar", "Baz"));

Page 47: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Map<String, String> map = new HashMap<String, String>() { { put("foo", "bar"); put("bar", "baz"); }};

Page 48: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Map<String, String> map = new HashMap<>() { { put("foo", "bar"); put("bar", "baz"); }};

Page 49: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Map<String, String> map = new HashMap<>() { { put("foo", "bar"); put("bar", "baz"); }};

Diamond.java:43: error: cannot infer type arguments for HashMap; Map<String, String> map = new HashMap<>() { ^ reason: cannot use '<>' with anonymous inner classes1 error

Page 50: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

class SomeClass<T extends Serializable & CharSequence> { }

Non-denotable type

Page 51: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

class SomeClass<T extends Serializable & CharSequence> { }

Non-denotable type

SomeClass<?> foo = new SomeClass<String>();SomeClass<?> fooInner = new SomeClass<String>() { };

SomeClass<?> bar = new SomeClass<>();

SomeClass<?> bar = new SomeClass<>() { };

Page 52: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

class SomeClass<T extends Serializable & CharSequence> { }

Non-denotable type

SomeClass<?> foo = new SomeClass<String>();SomeClass<?> fooInner = new SomeClass<String>() { };

SomeClass<?> bar = new SomeClass<>();

SomeClass<?> bar = new SomeClass<>() { };

No denotable typeto generate a class

Page 53: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Less ceremony when using generics

No diamond with inner classes

Page 54: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Simplified varargs

Page 55: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private static <T> void doSomethingBad(List<T> list, T... values) { values[0] = list.get(0);}

public static void main(String[] args) { List list = Arrays.asList("foo", "bar", "baz"); doSomethingBad(list, 1, 2, 3);}

Page 56: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private static <T> void doSomethingBad(List<T> list, T... values) { values[0] = list.get(0);}

public static void main(String[] args) { List list = Arrays.asList("foo", "bar", "baz"); doSomethingBad(list, 1, 2, 3);}

Heap Pollution: List = List<String>

This yields warnings + crash:

Page 57: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}

Page 58: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

private static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}

$ javac Good.java Note: Good.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.

Page 59: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

@SuppressWarnings({“unchecked”,“varargs”})

public static void main(String[] args) { List<String> list = new LinkedList<>(); doSomethingGood(list, "hi", "there", "!");}

$ javac Good.java $

Page 60: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

@SafeVarargsprivate static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}

static, final methods, constructors

Page 61: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Mark your code as safe for varargs

You can’t cheat with @SafeVarags

Remove @SuppressWarnings in client code and pay attention to real warnings

Page 62: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Multi-catch & more precise rethrow

Page 63: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));

Page 64: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (ClassNotFoundException e) { e.printStackTrace();} catch (InstantiationException e) { e.printStackTrace();} catch (IllegalAccessException e) { e.printStackTrace();} catch (NoSuchMethodException e) { e.printStackTrace();} catch (InvocationTargetException e) { e.printStackTrace();}

Page 65: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (Throwable t) { t.printStackTrace();}

Page 66: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (Throwable t) { t.printStackTrace();}

How about SecurityException?

Page 67: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { e.printStackTrace();}

Union of alternatives

Page 68: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

catch (SomeException e)

Now implicitly final unless assigned...

Page 69: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

static class SomeRootException extends Exception { }static class SomeChildException extends SomeRootException { }static class SomeOtherChildException extends SomeRootException { }

public static void main(String... args) throws Throwable {try { throw new SomeChildException();} catch (SomeRootException firstException) { try { throw firstException; } catch (SomeOtherChildException secondException) { System.out.println("I got you!"); }}

Page 70: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

static class SomeRootException extends Exception { }static class SomeChildException extends SomeRootException { }static class SomeOtherChildException extends SomeRootException { }

public static void main(String... args) throws Throwable {try { throw new SomeChildException();} catch (SomeRootException firstException) { try { throw firstException; } catch (SomeOtherChildException secondException) { System.out.println("I got you!"); }}

$ javac Imprecise.java Imprecise.java:13: error: exception SomeOtherChildException is never thrown in body of corresponding try statement } catch (SomeOtherChildException secondException) { ^1 error

Page 71: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Less clutterBe preciseDo not capture unintended exceptions

Better exception flow analysis

Page 72: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Minor additions

Page 73: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

// 123 in decimal, octal, hexadecimal and binarybyte decimal = 123;byte octal = 0_173;byte hexadecimal = 0x7b;byte binary = 0b0111_1011;

// Other valuesdouble doubleValue = 1.111_222_444F;long longValue = 1_234_567_898L;long longHexa = 0x1234_3b3b_0123_cdefL;

Page 74: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

public static boolean isTrue(String str) { switch(str.trim().toUpperCase()) { case "OK": case "YES": case "TRUE": return true;

case "KO": case "NO": case "FALSE": return false;

default: throw new IllegalArgumentException("Not a valid true/false string."); } }

Page 75: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

public static boolean isTrue(String s) { String str = s.trim().toUpperCase(); int jump = -1; switch(str.hashCode()) { case 2404: if (str.equals("KO")) { jump = 3; } break;(...) switch(jump) {(...) case 3: case 4: case 5: return false; default: throw new IllegalArgumentException( "Not a valid true/false string."); }}

Bucket

Real code

Page 76: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Fork and Join: Java Can Excel at Painless Parallel Programming Too!

Better Resource Management withJava SE 7: Beyond Syntactic Sugar

Oracle Technology Network

http://goo.gl/tostz

http://goo.gl/7ybgr

(more soon...)

Page 77: soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin

Julien Ponge

@jponge

http://gplus.to/jponge

http://julien.ponge.info/

[email protected]