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.

Julien Ponge

March 26, 2012
Tweet

More Decks by Julien Ponge

Other Decks in Programming

Transcript

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

    System.out.println(">>> Hello!"); } }; thread.start(); thread.join();
  2. 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; } }
  3. 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()); }
  4. n1 n2 n3 n4 n5 n6 n8 n7 n9 ...

    ... ... ... sum1 sum2 sum3 sum1 + sum2 sum3 + (...) total sum Sum of an array
  5. Load into RAM (1 thread) subfolders: List<Folder> documents: List<Document> Folder

    lines: List<String> Document Divide & conquer (#cores threads)
  6. 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()
  7. Split Fork subtasks Join subtasks Compose results Thread management Maximize

    parallelism Work stealing Your work ForkJoinPool
  8. 1" 2" 3" 4" 5" 6" 7" 2" 4" 6"

    8" 10" 12" Speedup& #cores
  9. 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!
  10. private void writeSomeData() throws IOException { DataOutputStream out = new

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

    DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close(); } what if...
  12. 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(); } } }
  13. 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!
  14. 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()); }
  15. 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()"); } }
  16. 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)
  17. 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
  18. 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(); } }
  19. 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(); } }
  20. 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(); } }
  21. 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(); } }
  22. 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(); } }
  23. 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)
  24. 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); } } }
  25. 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); } } }
  26. 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)
  27. 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"));
  28. 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"));
  29. 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
  30. 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<>() { };
  31. 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
  32. 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); }
  33. 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:
  34. 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.
  35. @SuppressWarnings({“unchecked”,“varargs”}) public static void main(String[] args) { List<String> list =

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

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

    with @SafeVarags Remove @SuppressWarnings in client code and pay attention to real warnings
  38. Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod

    = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));
  39. 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(); }
  40. 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(); }
  41. 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?
  42. 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
  43. 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!"); } }
  44. 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
  45. // 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;
  46. 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."); } }
  47. 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
  48. 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...)