• Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,091
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
21
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Java SE 7 Fork / Join FrameworkLanguage Evolutions (Project Coin) Julien Ponge
  • 2. Fork / Join
  • 3. java.lang.Thread java.lang.Runnable wait()<5 notify() synchronized
  • 4. Thread thread = new Thread() { public void run() { System.out.println(">>> Hello!"); }};thread.start();thread.join();
  • 5. java.util.concurrent executors concurrent queues concurrent collections atomic variables5, 6 synchronization patterns rich locks
  • 6. 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; }}
  • 7. 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());}
  • 8. 1.0 Threads made easy1.11.21.31.4 5 Concurrency made easier 6 7 Parallelism made easier
  • 9. Sum of an arrayn1 n2 n3 n4 n5 n6 n7 n8 n9 ... ... ... ... sum1 sum2 sum3 sum1 + sum2 sum3 + (...) total sum
  • 10. A need for divide and conquer
  • 11. ForkJoinPool Your workThread management SplitMaximize parallelism Fork subtasks Work stealing Join subtasks Compose results
  • 12. ForkJoinTask join() join() RecursiveAction fork() fork() vs RecursiveTaskChild ForkJoinTask Child ForkJoinTask
  • 13. 16 Folder word counting task 10 5 1Document word Document word Folder word counting task counting task counting task 3 2 fork() Document word Document word n join() counting task counting task
  • 14. class FolderSearchTask extends RecursiveTask<Long> {(...) protected Long compute() { long count = 0L; List<RecursiveTask<Long>> forks = new LinkedList<>(); for (Folder subFolder : folder.getSubFolders()) { FolderSearchTask task = new FolderSearchTask(subFolder, searchedWord); forks.add(task); task.fork(); } for (Document document : folder.getDocuments()) { DocumentSearchTask task = new DocumentSearchTask(document, searchedWord); forks.add(task); task.fork(); } for (RecursiveTask<Long> task : forks) { count = count + task.join(); } return count; }(...)}
  • 15. class FolderSearchTask extends RecursiveTask<Long> {(...) protected Long compute() { long count = 0L; List<RecursiveTask<Long>> forks = new LinkedList<>(); Split for (Folder subFolder : folder.getSubFolders()) { FolderSearchTask task = new FolderSearchTask(subFolder, searchedWord); forks.add(task); task.fork(); } for (Document document : folder.getDocuments()) { DocumentSearchTask task = new DocumentSearchTask(document, searchedWord); forks.add(task); task.fork(); } for (RecursiveTask<Long> task : forks) { count = count + task.join(); } return count; }(...)}
  • 16. class FolderSearchTask extends RecursiveTask<Long> {(...) protected Long compute() { long count = 0L; List<RecursiveTask<Long>> forks = new LinkedList<>(); for (Folder subFolder : folder.getSubFolders()) { FolderSearchTask task = new FolderSearchTask(subFolder, searchedWord); forks.add(task); } task.fork(); Fork for (Document document : folder.getDocuments()) { DocumentSearchTask task = new DocumentSearchTask(document, searchedWord); forks.add(task); task.fork(); } for (RecursiveTask<Long> task : forks) { count = count + task.join(); } return count; }(...)}
  • 17. class FolderSearchTask extends RecursiveTask<Long> {(...) protected Long compute() { long count = 0L; List<RecursiveTask<Long>> forks = new LinkedList<>(); for (Folder subFolder : folder.getSubFolders()) { FolderSearchTask task = new FolderSearchTask(subFolder, searchedWord); forks.add(task); task.fork(); } for (Document document : folder.getDocuments()) { DocumentSearchTask task = new DocumentSearchTask(document, searchedWord); forks.add(task); task.fork(); } for (RecursiveTask<Long> task : forks) { count = count + task.join(); } return count; Join, Compose }(...)}
  • 18. (F/J demo)
  • 19. Speedup&7"6"5"4"3"2"1" 2" 4" 6" 8" 10" 12" #cores
  • 20. No I/ONo synchronization / locksDecompose in simple recursive tasksDo not decompose below a thresholdTake advantage of multicores with no painYou have more F/J candidate algorithms thanyou think!
  • 21. try-with-resources
  • 22. private void writeSomeData() throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close();}
  • 23. private void writeSomeData() throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close();} what if...
  • 24. 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(); } }}
  • 25. 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!
  • 26. 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());}
  • 27. 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()"); }}
  • 28. AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}
  • 29. 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)
  • 30. AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();} MyException m asked by Run>>> work() time Exception >>> 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)
  • 31. “Caused by” ≠ “Also happened”
  • 32. 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(); }}
  • 33. 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(); }}
  • 34. 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(); }}
  • 35. 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(); }}
  • 36. 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(); }}
  • 37. try (AutoClose autoClose = new AutoClose()) { autoClose.work();}
  • 38. 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)
  • 39. 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); } }}
  • 40. public void compress(String input, String output) throws IOException { public void compress(String paramString1, String paramString2) try(         throws IOException { FileInputStream fin = new FileInputStream(input);     FileInputStream localFileInputStream = new FileInputStream(paramString1); FileOutputStream fout = new FileOutputStream(output);     Object localObject1 = null; GZIPOutputStream out = new GZIPOutputStream(fout)     try { ) {         FileOutputStream localFileOutputStream = new FileOutputStream(paramString2); byte[] buffer = new byte[4096];         Object localObject2 = null; int nread = 0;         try { while ((nread = fin.read(buffer)) != -1) {             GZIPOutputStream localGZIPOutputStream = new GZIPOutputStream(localFileOutputStream); out.write(buffer, 0, nread);             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();             }         }     } }
  • 41. Not just syntactic sugarClutter-free, correct codeclose(): - 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)
  • 42. Diamond <>
  • 43. List<String> strings = new LinkedList<Integer>();Map<String, List<String>> contacts = new HashMap<Integer, String>();
  • 44. 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"));
  • 45. 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"));
  • 46. Map<String, String> map = new HashMap<String, String>() { { put("foo", "bar"); put("bar", "baz"); }};
  • 47. Map<String, String> map = new HashMap<>() { { put("foo", "bar"); put("bar", "baz"); }};
  • 48. 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
  • 49. class SomeClass<T extends Serializable & CharSequence> { } Non-denotable type
  • 50. class SomeClass<T extends Serializable & CharSequence> { } Non-denotable typeSomeClass<?> foo = new SomeClass<String>();SomeClass<?> fooInner = new SomeClass<String>() { };SomeClass<?> bar = new SomeClass<>();SomeClass<?> bar = new SomeClass<>() { };
  • 51. class SomeClass<T extends Serializable & CharSequence> { } Non-denotable typeSomeClass<?> foo = new SomeClass<String>();SomeClass<?> fooInner = new SomeClass<String>() { };SomeClass<?> bar = new SomeClass<>();SomeClass<?> bar = new SomeClass<>() { }; No denotable type to generate a class
  • 52. Less ceremony when using genericsNo diamond with inner classes
  • 53. Simplified varargs
  • 54. 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);}
  • 55. This yields warnings + crash: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>
  • 56. private static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}
  • 57. private static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}$ javac Good.javaNote: Good.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.
  • 58. @SuppressWarnings({“unchecked”,“varargs”})public static void main(String[] args) { List<String> list = new LinkedList<>(); doSomethingGood(list, "hi", "there", "!");}$ javac Good.java$
  • 59. static, final methods, constructors@SafeVarargsprivate static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}
  • 60. Mark your code as safe for varargsYou can’t cheat with @SafeVaragsRemove @SuppressWarnings in client codeand pay attention to real warnings
  • 61. Multi-catch & more precise rethrow
  • 62. Class<?> stringClass = Class.forName("java.lang.String");Object instance = stringClass.newInstance();Method toStringMethod = stringClass.getMethod("toString");System.out.println(toStringMethod.invoke(instance));
  • 63. 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();}
  • 64. 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();}
  • 65. 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?
  • 66. 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
  • 67. catch (SomeException e)Now implicitly final unless assigned...
  • 68. 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!"); }}
  • 69. 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.javaImprecise.java:13: error: exception SomeOtherChildException is never thrown in body ofcorresponding try statement } catch (SomeOtherChildException secondException) { ^1 error
  • 70. Less clutterBe preciseDo not capture unintended exceptionsBetter exception flow analysis
  • 71. Minor additions
  • 72. // 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;
  • 73. 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."); }}
  • 74. 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; Bucket } break;(...) switch(jump) {(...) case 3: case 4: case 5: return false; default: Real code throw new IllegalArgumentException( "Not a valid true/false string."); }}
  • 75. Oracle Technology Network (more soon...) Fork and Join: Java Can Excel at Painless Parallel Programming Too! http://goo.gl/tostz Better Resource Management with Java SE 7: Beyond Syntactic Sugar http://goo.gl/7ybgr
  • 76. Julien Ponge @jponge http://julien.ponge.info/julien.ponge@insa-lyon.fr