Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LavaJUG - Java 7

LavaJUG - Java 7

Slides of my Java 7 talk at the LavaJUG in november 2011.

50a17cd98aab2cc4d8e144741e11b1b7?s=128

Julien Ponge

March 26, 2012
Tweet

More Decks by Julien Ponge

Other Decks in Programming

Transcript

  1. Lava JUG Java 7 — Julien Ponge @jponge

  2. None
  3. Fork / Join Project Coin NIO.2 invokedynamic (...)

  4. Fork / Join

  5. synchronized wait() notify() < 5 java.lang.Thread java.lang.Runnable

  6. Thread thread = new Thread() { public void run() {

    System.out.println(">>> Hello!"); } }; thread.start(); thread.join();
  7. java.util.concurrent executors concurrent queues concurrent collections atomic variables synchronization patterns

    rich locks 5, 6
  8. 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; } }
  9. 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()); }
  10. Threads made easy Concurrency made easier Parallelism made easier 1.0

    1.1 1.2 1.3 1.4 5 6 7
  11. n1 n2 n3 n4 n5 n6 n8 n7 n9 ...

    ... ... ... sum1 sum2 sum3 sum1 + sum2 sum3 + (...) total sum Sum of an array
  12. How many occurrences of “java.util.List” in this filesystem tree?

  13. Load into RAM (1 thread) subfolders: List<Folder> documents: List<Document> Folder

    lines: List<String> Document Divide & conquer (#cores threads)
  14. Document word counting task Document word counting task Folder word

    counting task Folder word counting task Document word counting task Document word counting task 3 n 2 5 1 10 16 fork() join()
  15. Split Fork subtasks Join subtasks Compose results Thread management Maximize

    parallelism Work stealing Your work ForkJoinPool
  16. Child ForkJoinTask fork() fork() join() join() Child ForkJoinTask ForkJoinTask RecursiveAction

    vs RecursiveTask
  17. (Some F/J Code)

  18. 1" 2" 3" 4" 5" 6" 7" 2" 4" 6"

    8" 10" 12" Speedup& #cores
  19. No I/O No synchronization / locks Decompose in simple recursive

    tasks Do not decompose below a threshold Take advantage of multicores with no pain You have more F/J candidate algorithms than you think!
  20. try-with-resources

  21. private void writeSomeData() throws IOException { DataOutputStream out = new

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

    DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close(); } what if...
  23. 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(); } } }
  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(); } } } ...this is still far from correct!
  25. 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()); }
  26. 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()"); } }
  27. AutoClose autoClose = new AutoClose(); try { autoClose.work(); } finally

    { autoClose.close(); }
  28. 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)
  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) MyException masked by RuntimeException
  30. “Caused by” ≠ “Also happened”

  31. 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(); } }
  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. try (AutoClose autoClose = new AutoClose()) { autoClose.work(); }

  37. 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)
  38. 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); } } }
  39. 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); } } }
  40. Not just syntactic sugar Clutter-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)
  41. Diamond <>

  42. List<String> strings = new LinkedList<Integer>(); Map<String, List<String>> contacts = new

    HashMap<Integer, String>();
  43. 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"));
  44. 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"));
  45. Map<String, String> map = new HashMap<String, String>() { { put("foo",

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

    put("bar", "baz"); } };
  47. 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 classes 1 error
  48. class SomeClass<T extends Serializable & CharSequence> { } Non-denotable type

  49. 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<>() { };
  50. 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 type to generate a class
  51. Less ceremony when using generics No diamond with inner classes

  52. Simplified varargs

  53. 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); }
  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); } Heap Pollution: List = List<String> This yields warnings + crash:
  55. private static <T> void doSomethingGood(List<T> list, T... values) { for

    (T value : values) { list.add(value); } }
  56. 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.
  57. @SuppressWarnings({“unchecked”,“varargs”}) public static void main(String[] args) { List<String> list =

    new LinkedList<>(); doSomethingGood(list, "hi", "there", "!"); } $ javac Good.java $
  58. @SafeVarargs private static <T> void doSomethingGood(List<T> list, T... values) {

    for (T value : values) { list.add(value); } } static, final methods, constructors
  59. Mark your code as safe for varargs You can’t cheat

    with @SafeVarags Remove @SuppressWarnings in client code and pay attention to real warnings
  60. Multi-catch & more precise rethrow

  61. Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod

    = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));
  62. 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(); }
  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 (Throwable t) { t.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(); } How about SecurityException?
  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 (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { e.printStackTrace(); } Union of alternatives
  66. catch (SomeException e) Now implicitly final unless assigned...

  67. 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!"); } }
  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!"); } } $ javac Imprecise.java Imprecise.java:13: error: exception SomeOtherChildException is never thrown in body of corresponding try statement } catch (SomeOtherChildException secondException) { ^ 1 error
  69. Less clutter Be precise Do not capture unintended exceptions Better

    exception flow analysis
  70. Minor additions

  71. // 123 in decimal, octal, hexadecimal and binary byte decimal

    = 123; byte octal = 0_173; byte hexadecimal = 0x7b; byte binary = 0b0111_1011; // Other values double doubleValue = 1.111_222_444F; long longValue = 1_234_567_898L; long longHexa = 0x1234_3b3b_0123_cdefL;
  72. 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."); } }
  73. 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
  74. Fork and Join: Java Can Excel at Painless Parallel Programming

    Too! Better Resource Management with Java SE 7: Beyond Syntactic Sugar Oracle Technology Network http://goo.gl/tostz http://goo.gl/7ybgr (more soon...)
  75. Julien Ponge @jponge http://gplus.to/jponge http://julien.ponge.info/ julien.ponge@insa-lyon.fr