Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

50 nouvelles choses que l'on peut faire avec Java 8

45 120 vues

Publié le

Java 8, c'est bien sûr l'arrivée des lambdas, des Stream et des Collectors. Mais ce n'est pas que cela. Plein de nouvelles choses sont aussi offertes : un nouvelle API pour les dates, un nouveau moteur Javascript, une nouvelle version de JavaFX, une nouvelle ConcurrentHashMap, une nouvelle HashMap, des nouveautés dans le domaine de la concurrence, et toutes sortes de petites choses qui vont nous faciliter la vie, que l'on se propose de passer en revue ici.

Publié dans : Formation, Technologie
  • Hi All, We are planning to start Hadoop online training batch on this week... If any one interested to attend the demo please register in our website... For this batch we are also provide everyday recorded sessions with Materials. For more information feel free to contact us : siva@keylabstraining.com. For Course Content and Recorded Demo Click Here : http://www.keylabstraining.com/hadoop-online-training-hyderabad-bangalore
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Hi All, We are planning to start new devops online batch on this week... If any one interested to attend the demo please register in our website... For this batch we are also provide everyday recorded sessions with Materials. For more information feel free to contact us : siva@keylabstraining.com. For Course Content and Recorded Demo Click Here : http://www.keylabstraining.com/devops-online-training-tutorial
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • @undefined Adam Bien a donné un exemple plus simple, qui fait qu'il faut juste convertir directement en char si on ne veut pas faire du mapping
    'hey duke'.chars()
    .map(Character::toUpperCase)
    .forEach(c -> System.out.print((char)c));
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Une petite remarque au slide 11, c'est l'enum ChronoUnit qui implémente TemporalUnit, il fallait faire
    elapsed.plus(2L, ChronoUnit.SECONDS)
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • C'est très cool, 50 nouvelles choses!!!
    Au fait je voulais aussi vous faire ce remarque quand je travaillais et que ça ne compilait pas.
    Moi au lieu de faire un mapToObj j'ai plutôt comme ça:
    stream.map(Character::toUpperCase)
    .forEach(s->out.printf('%c',s);
    Une instruction de moins.
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

50 nouvelles choses que l'on peut faire avec Java 8

  1. 1. @JosePaumard nouvelles choses que l’on peut faire avec Java
  2. 2. Questions ? #50new8 @JosePaumard
  3. 3. Date
  4. 4. @JosePaumard#50new8 Date : Instant Un instant est un point de la ligne du temps Instant start = Instant.now() ; Instant end = Instant.now() ;
  5. 5. @JosePaumard#50new8 Date : Duration Une « duration » est une durée Instant start = Instant.now() ; Instant end = Instant.now() ; Duration elapsed = Duration.between(start, end) ; long millis = elapsed.toMillis() ;
  6. 6. @JosePaumard#50new8 Date : Duration On peut faire des calculs sur les « durations » Instant start = Instant.now() ; Instant end = Instant.now() ; Duration elapsed = Duration.between(start, end) ; long millis = elapsed.toMillis() ; elapsed.plus(2L, TemporalUnit.SECONDS) ;
  7. 7. @JosePaumard#50new8 Date : LocalDate Une LocalDate est une date empirique LocalDate now = LocalDate.now() ; LocalDate shakespeareDoB = LocaleDate.of(1564, Month.APRIL, 23) ;
  8. 8. @JosePaumard#50new8 Date : Period Une Period est une durée entre LocalDate LocalDate now = LocalDate.now() ; LocalDate shakespeareDoB = LocalDate.of(1564, Month.APRIL, 23) ; Period p = shakespeareDoB.until(now) ; System.out.println("# years = " + p.getYears()) ; > # years = 449
  9. 9. @JosePaumard#50new8 Date : Period Une Period est une durée entre LocalDate LocalDate now = LocalDate.now() ; LocalDate shakespeareDoB = LocalDate.of(1564, Month.APRIL, 23) ; Period p = shakespeareDoB.until(now) ; System.out.println("# years = " + p.getYears()) ; long days = shakespeareDoB.until(now, ChronoUnit.DAYS) ; System.out.println("# days = " + days) ; // 164_354
  10. 10. @JosePaumard#50new8 Date : TemporalAdjuster Permet de trouver une date à partir d’une autre LocalDate now = LocalDate.now() ; LocalDate nextSunday = now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
  11. 11. @JosePaumard#50new8 Date : TemporalAdjuster Permet de trouver une date à partir d’une autre 14 méthodes statiques dans la boite à outils firstDayOfMonth(), lastDayOfYear() firstDayOfNextMonth() LocalDate now = LocalDate.now() ; LocalDate nextSunday = now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
  12. 12. @JosePaumard#50new8 Date : TemporalAdjuster Permet de trouver une date à partir d’une autre 14 méthodes statiques dans la boite à outils firstInMonth(DayOfWeek.MONDAY) next(DayOfWeek.FRIDAY) LocalDate now = LocalDate.now() ; LocalDate nextSunday = now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
  13. 13. @JosePaumard#50new8 Date : LocalTime Permet de coder une heure empirique : 10h20 LocalTime now = LocalTime.now() ; LocalTime time = LocalTime.of(10, 20) ; // 10h20
  14. 14. @JosePaumard#50new8 Date : LocalTime Permet de coder une heure empirique : 10h20 LocalTime now = LocalTime.now() ; LocalTime time = LocalTime.of(10, 20) ; // 10h20 LocalTime lunchTime = LocalTime.of(12, 30) ; LocalTime coffeeTime = lunchTime.plusHours(2) ; // 14h20
  15. 15. @JosePaumard#50new8 Date : ZonedTime Permet de coder des heures localisées Set<String> allZonesIds = ZoneId.getAvailableZoneIds() ; String ukTZ = ZoneId.of("Europe/London") ;
  16. 16. @JosePaumard#50new8 Date : ZonedTime Permet de coder des heures localisées System.out.println( ZonedDateTime.of( 1564, Month.APRIL.getValue(), 23, // year / month / day 10, 0, 0, 0, // h / mn / s / nanos ZoneId.of("Europe/London")) ); // prints 1564-04-23T10:00-00:01:15[Europe/London]
  17. 17. @JosePaumard#50new8 Date : ZonedTime On peut faire des calculs sur les heures localisées ZonedDateTime currentMeeting = ZonedDateTime.of( LocalDate.of(2014, Month.APRIL, 18), // LocalDate LocalTime.of(9, 30), // LocalTime ZoneId.of("Europe/London") ) ; ZonedDateTime nextMeeting = currentMeeting.plus(Period.ofMonth(1)) ;
  18. 18. @JosePaumard#50new8 Date : ZonedTime On peut faire des calculs sur les heures localisées ZonedDateTime currentMeeting = ZonedDateTime.of( LocalDate.of(2014, Month.APRIL, 18), // LocalDate LocalTime.of(9, 30), // LocalTime ZoneId.of("Europe/London") ) ; ZonedDateTime nextMeeting = currentMeeting.plus(Period.ofMonth(1)) ; ZonedDateTime nextMeetingUS = nextMeeting.withZoneSameInstant(ZoneId.of("US/Central")) ;
  19. 19. @JosePaumard#50new8 Date : Formattage Classe utilitaire : DateTimeFormatter ZonedDateTime nextMeetingUS = nextMeeting.withZoneSameInstant(ZoneId.of("US/Central")); System.out.println( DateTimeFormatter.ISO_DATE_TIME.format(nextMeetingUS) ); // prints 2014-04-12T03:30:00-05:00[US/Central] System.out.println( DateTimeFormatter.RFC_1123_DATE_TIME.format(nextMeetingUS) ); // prints Sat, 12 Apr 2014 03:30:00 -0500
  20. 20. @JosePaumard#50new8 Date : liens avec java.util.Date Classe utilitaire : DateTimeFormatter Date date = Date.from(instant); // legacy -> new API Instant instant = date.toInstant(); // API -> legacy
  21. 21. @JosePaumard#50new8 Date : liens avec java.util.Date Classe utilitaire : DateTimeFormatter Date date = Date.from(instant); // legacy -> new API Instant instant = date.toInstant(); // API -> legacy TimeStamp time = TimeStamp.from(instant); // legacy -> new API Instant instant = time.toInstant(); // API -> legacy
  22. 22. @JosePaumard#50new8 Date : liens avec java.util.Date Classe utilitaire : DateTimeFormatter Date date = Date.from(instant); // legacy -> new API Instant instant = date.toInstant(); // API -> legacy TimeStamp time = TimeStamp.from(instant); // legacy -> new API Instant instant = time.toInstant(); // API -> legacy Date date = Date.from(localDate); // legacy -> new API LocalDate localDate = date.toLocalDate(); // API -> legacy
  23. 23. @JosePaumard#50new8 Date : liens avec java.util.Date Classe utilitaire : DateTimeFormatter Date date = Date.from(instant); // legacy -> new API Instant instant = date.toInstant(); // API -> legacy TimeStamp time = TimeStamp.from(instant); // legacy -> new API Instant instant = time.toInstant(); // API -> legacy Date date = Date.from(localDate); // legacy -> new API LocalDate localDate = date.toLocalDate(); // API -> legacy Time time = Time.from(localTime); // legacy -> new API LocalTime localTime = time.toLocalTime(); // API -> legacy
  24. 24. String
  25. 25. @JosePaumard#50new8 String : Stream Un stream sur les lettres qui composent une String String s = "bonjour" ; IntStream stream = s.chars() ; stream.forEach(Sytem.out::println) ;
  26. 26. @JosePaumard#50new8 String : Stream Un stream sur les lettres qui composent une String Affiche : String s = "bonjour" ; IntStream stream = s.chars() ; stream .map(String::toUpperCase) .forEach(Sytem.out::print) ; > BONJOUR
  27. 27. @JosePaumard#50new8 String : expressions régulières Construction de Stream à partir d’une regexp // book est une grrrande chaîne Stream<String> words = Pattern .compile("[^p{javaLetter}]") .splitAsStream(book) ;
  28. 28. @JosePaumard#50new8 String : concaténation Le naïf écrit : String s1 = "bonjour" ; String s2 = "le monde" ; String s3 = s1 + " " + s2 ;
  29. 29. @JosePaumard#50new8 String : concaténation L’ignorant lui dit d’écrire : StringBuilder sb1 = new StringBuilder("bonjour") ; sb1.append(" le monde") ; String s3 = sb1.toString() ;
  30. 30. @JosePaumard#50new8 String : concaténation L’ignorant lui dit d’écrire : String s1 = "bonjour" ; String s2 = "le monde" ; String s3 = s1 + " " + s2 ;LINENUMBER 10 L2 NEW java/lang/StringBuilder DUP ALOAD 1 INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String; INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V LDC " " INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder; ALOAD 2 INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String; ASTORE 3
  31. 31. @JosePaumard#50new8 String : concaténation Le spécialiste Java 8 écrit // The JDK 8 way StringJoiner sj = new StringJoiner(", ") ; sj.add("one").add("two").add("three") ; String s = sj.toString() ; System.out.println(s) ;
  32. 32. @JosePaumard#50new8 String : concaténation Le spécialiste Java 8 écrit Ce qui affiche // The JDK 8 way StringJoiner sj = new StringJoiner(", ") ; sj.add("one").add("two").add("three") ; String s = sj.toString() ; System.out.println(s) ; > one, two, three
  33. 33. @JosePaumard#50new8 String : concaténation Le spécialiste Java 8 écrit Ce qui affiche // The JDK 8 way StringJoiner sj = new StringJoiner(", ", "{", "}") ; sj.add("one").add("two").add("three") ; String s = sj.toString() ; System.out.println(s) ; > {one, two, three}
  34. 34. @JosePaumard#50new8 String : concaténation Le spécialiste Java 8 écrit Ce qui affiche // The JDK 8 way StringJoiner sj = new StringJoiner(", ", "{", "}") ; // on ne met rien dedans String s = sj.toString() ; System.out.println(s) ; > {}
  35. 35. @JosePaumard#50new8 String : concaténation S’utilise aussi à partir de String directement Ce qui affiche // From the String class, with a vararg String s = String.join(", ", "one", "two", "three"); System.out.println(s); > one, two, three
  36. 36. @JosePaumard#50new8 String : concaténation S’utilise aussi à partir de String directement Ce qui affiche // From the String class, with an Iterable String [] tab = {"one", "two", "three"} ; String s = String.join(", ", tab) ; System.out.println(s) ; > one, two, three
  37. 37. I/O
  38. 38. @JosePaumard#50new8 I/O : lecture de fichiers texte Stream implémente AutoCloseable // Java 7 : try with resources and use of Paths Path path = Paths.get("d:", "tmp", "debug.log"); try (Stream<String> stream = Files.lines(path)) { stream.filter(line -> line.contains("ERROR")) .findFirst() .ifPresent(System.out::println); } catch (IOException ioe) { // handle the exception }
  39. 39. @JosePaumard#50new8 I/O : lecture d’un répertoire Files.list retourne les fichiers du répertoire // Java 7 : try with resources and use of Paths Path path = Paths.get("c:", "windows"); try (Stream<Path> stream = Files.list(path)) { stream.filter(path -> path.toFile().isDirectory()) .forEach(System.out::println); } catch (IOException ioe) { // handle the exception }
  40. 40. @JosePaumard#50new8 I/O : lecture d’une arborescence Files.walk retourne les fichiers du sous-arbre // Java 7 : try with resources and use of Paths Path path = Paths.get("c:", "windows"); try (Stream<Path> stream = Files.walk(path)) { stream.filter(path -> path.toFile().isDirectory()) .forEach(System.out::println); } catch (IOException ioe) { // handle the exception }
  41. 41. @JosePaumard#50new8 I/O : lecture d’une arborescence Files.walk retourne les fichiers du sous-arbre, profondeur // Java 7 : try with resources and use of Paths Path path = Paths.get("c:", "windows"); try (Stream<Path> stream = Files.walk(path, 2)) { stream.filter(path -> path.toFile().isDirectory()) .forEach(System.out::println); } catch (IOException ioe) { // handle the exception }
  42. 42. List
  43. 43. @JosePaumard#50new8 Iterable : forEach ForEach : itère sur tous les éléments, prend un consumer Ne marche pas sur les tableaux // méthode forEach sur Iterable List<String> strings = Arrays.asList("one", "two", "three") ; strings.forEach(System.out::println) ; > one, two, three
  44. 44. @JosePaumard#50new8 Collection : removeIf Retire un objet : prend un prédicat // removes an element on a predicate Collection<String> strings = Arrays.asList("one", "two", "three", "four"); // works « in place », no Collections.unmodifiable... Collection<String> list = new ArrayList<>(strings); // returns true if the list has been modified boolean b = list.removeIf(s -> s.length() > 4); > one, two, four
  45. 45. @JosePaumard#50new8 List : replaceAll Remplace un objet par sa transformée // removes an element on a predicate Collection<String> strings = Arrays.asList("one", "two", "three", "four"); // works « in place », no Collections.unmodifiable... Collection<String> list = new ArrayList<>(strings); // returns nothing list.replaceAll(String::toUpperCase); > ONE, TWO, THREE, FOUR
  46. 46. @JosePaumard#50new8 List : sort Tri une liste en place, prend un comparateur // removes an element on a predicate Collection<String> strings = Arrays.asList("one", "two", "three", "four"); // works « in place », no Collections.unmodifiable... Collection<String> list = new ArrayList<>(strings); // returns nothing list.sort(Comparator.naturalOrder()) ; > four, one, three, two
  47. 47. Arrays Parallel
  48. 48. @JosePaumard#50new8 Parallel Arrays Arrays.parallelSetAll long [] array = new long [...] ; Arrays.parallelSetAll(array, index -> index % 3) ; System.out.println(Arrays.toString(array)) ;
  49. 49. @JosePaumard#50new8 Parallel Arrays Arrays.parallelPrefix : fold right long [] array = new long [...] ; Arrays.parallelPrefix(array, (l1, l2) -> l1 + l2) ; System.out.println(Arrays.toString(array)) ; long [] array = {1L, 1L, 1L, 1L} ; > [1, 2, 3, 4]
  50. 50. @JosePaumard#50new8 Parallel Arrays Arrays.sort : tri en place long [] array = new long [...] ; Arrays.parallelSort(array) ; System.out.println(Arrays.toString(array)) ;
  51. 51. Comparator
  52. 52. @JosePaumard#50new8 Comparator ! Que dire de plus ? Comparator.naturalOrder()
  53. 53. @JosePaumard#50new8 Comparator ! Que dire de plus ? Comparator.naturalOrder() public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE; }
  54. 54. @JosePaumard#50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; }
  55. 55. @JosePaumard#50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c1.compareTo(c2); } }
  56. 56. @JosePaumard#50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c1.compareTo(c2); } public Comparator<Comparable<Object>> reversed() { return Comparator.reverseOrder(); } }
  57. 57. @JosePaumard#50new8 Comparator ! Que dire de plus ? Comparator.comparingBy(Person::getLastName) .thenComparing(Person::getFirstName) .thenComparing(Person::getAge)
  58. 58. Map
  59. 59. @JosePaumard#50new8 Map : forEach Prend un BiConsumer // the existing map Map<String, Person> map = ... ; map.forEach( (key, value) -> System.out.println(key + " -> " + value) ) ;
  60. 60. @JosePaumard#50new8 Map : replace Remplace une valeur avec sa clé // the existing map Map<String, Person> map = ... ; // key, newValue map.replace("six", john) ; // key, oldValue, newValue map.replace("six", peter, john) ;
  61. 61. @JosePaumard#50new8 Map : replaceAll Transforme toutes les valeurs // the existing map Map<String, Person> map = ... ; // key, oldValue map.replaceAll( (key, value) -> key + " -> " + value ; ) ;
  62. 62. @JosePaumard#50new8 Map : remove Retire les paires clés / valeurs // the existing map Map<String, Person> map = ... ; // key, oldValue map.remove("six", john) ;
  63. 63. @JosePaumard#50new8 Map : compute Calcule une valeur à partir de la clé et la valeur existante, et d’une fonction qui fusionne la paire clé / valeur // the existing map Map<String, Person> map = ... ; // key, oldValue map.compute( key, (key, value) -> key + "::" + value ) ;
  64. 64. @JosePaumard#50new8 Map : merge Calcule une valeur à partir de la clé, de l’actuelle valeur si elle existe, et d’une fonction qui fusionne les valeurs // the existing map Map<String, Person> map = ... ; // key, otherValue map.merge( key, otherValue, (value, otherValue) -> value.concat(", ").concat(otherValue) ) ;
  65. 65. @JosePaumard#50new8 Map : putIfAbsent Ajoute une paire clé / valeur si la clé n’est pas déjà dans la table // the existing map Map<String, Person> map = ... ; // key, newValue map.putIfAbsent("un", john) ;
  66. 66. @JosePaumard#50new8 Map : computeIfAbsent Si la clé est absente : associe une valeur calculée par exécution de la fonction. Dans tous les cas : retourne la valeur (nouvelle ou ancienne) // the existing map Map<String, Map<String, Person>> map = ... ; // key, newValue map.computeIfAbsent( "un", key -> new HashMap<>() ) .put(".un", john) ;
  67. 67. @JosePaumard#50new8 Map : computeIfPresent Si la clé est présente : associe une valeur calculée par exécution de la fonction. Retourne la valeur. // the existing map Map<String, Map<String, Person>> map = ... ; // key, newValue map.computeIfPresent( "un", map, (key, value) -> ... // la nouvelle valeur ) .put(".un", john) ;
  68. 68. Completable Future
  69. 69. @JosePaumard#50new8 CompletableFuture Extension de Future CompletableFuture<String> page = CompletableFuture.supplyAsync( ) ;
  70. 70. @JosePaumard#50new8 CompletableFuture Extension de Future CompletableFuture<String> page = CompletableFuture.supplyAsync( () -> readWebPage(url) ) ;
  71. 71. @JosePaumard#50new8 CompletableFuture Permet de créer des pipelines CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenApply(content -> getImages(content)) ;
  72. 72. @JosePaumard#50new8 CompletableFuture Permet de créer des pipelines CompletableFuture<List<Image>> images = CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenApply(content -> getImages(content)) ; // function
  73. 73. @JosePaumard#50new8 CompletableFuture thenCompose : composition de tâches dans le futur CompletableFuture<List<Image>> cf = CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenCompose(content -> getImages(content))
  74. 74. @JosePaumard#50new8 CompletableFuture thenCompose : composition de tâches dans le futur CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenCompose(content -> getImages(content)) .thenApply(image -> writeToDisk(image)) ; // retourne CF<Boolean>
  75. 75. @JosePaumard#50new8 CompletableFuture thenCompose : composition de tâches dans le futur List<CompletableFuture<Boolean>> result = CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenCompose(content -> getImages(content)) .thenApply(image -> writeToDisk(image)) ; // retourne CF<Boolean>
  76. 76. @JosePaumard#50new8 CompletableFuture allOf : composition de tâches dans le futur (anyOf existe) CompletableFuture.allOf( CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenCompose(content -> getImages(content)) .thenApply(image -> writeToDisk(image)) ) .join() ;
  77. 77. @JosePaumard#50new8 CompletableFuture thenCombine : combine plusieurs CF Applique la fonction une fois les deux CF exécutés CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // retourne la combinaison // des résultats des CF
  78. 78. @JosePaumard#50new8 CompletableFuture thenCombine : combine plusieurs CF Applique la fonction une fois les deux CF exécutés thenAcceptBoth, runAfterBoth CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // retourne la combinaison // des résultats des CF
  79. 79. @JosePaumard#50new8 CompletableFuture applyToEither : utilise le premier résultat disponible CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.applyToEither(cf2, (b) -> ...) ; // s’applique au résultat // du premier CF dispo
  80. 80. @JosePaumard#50new8 CompletableFuture applyToEither : utilise le premier résultat disponible acceptEither, runAfterEither CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.applyToEither(cf2, (b) -> ...) ; // s’applique au résultat // du premier CF dispo
  81. 81. Concurrence
  82. 82. @JosePaumard#50new8 Variables atomiques On avait : AtomicLong atomic = new AtomicLong() ; long l1 = atomic.incrementAndGet() ;
  83. 83. @JosePaumard#50new8 Variables atomiques On a : AtomicLong atomic = new AtomicLong() ; long l1 = atomic.incrementAndGet() ; long l2 = atomic.updateAndGet(l -> l*2 + 1) ;
  84. 84. @JosePaumard#50new8 Variables atomiques On a : AtomicLong atomic = new AtomicLong() ; long l1 = atomic.incrementAndGet() ; long l2 = atomic.updateAndGet(l -> l*2 + 1) ; long l3 = atomic.accumulateAndGet(12L, (l1, l2) -> l1 % l2) ;
  85. 85. @JosePaumard#50new8 LongAdder On a : LongAdded adder = new LongAdder() ; adder.increment() ; // dans un thread adder.increment() ; // dans un autre thread adder.increment() ; // encore dans un autre thread long sum = adder.sum() ;
  86. 86. @JosePaumard#50new8 LongAccumulator Même chose, mais on généralise : LongAccumulator accu = new LongAccumulator((l1, l2) -> Long.max(l1, l2), 0L) ; accu.accumulate(value1) ; // dans un thread accu.accumulate(value2) ; // dans un autre thread accu.accumulate(value2) ; // encore dans un autre thread long sum = accu.longValue() ;
  87. 87. @JosePaumard#50new8 StampedLock Un lock avec lecture optimiste StampedLock sl= new StampedLock() ; long stamp = sl.writeLock() ; try { ... } finally { sl.unlockWrite(stamp) ; } long stamp = sl.readLock() ; try { ... } finally { sl.unlockRead(stamp) ; }
  88. 88. @JosePaumard#50new8 StampedLock Un lock avec lecture optimiste Exclusivité entre read / write, mais… StampedLock sl= new StampedLock() ; long stamp = sl.writeLock() ; try { ... } finally { sl.unlockWrite(stamp) ; } long stamp = sl.readLock() ; try { ... } finally { sl.unlockRead(stamp) ; }
  89. 89. @JosePaumard#50new8 StampedLock Un lock avec lecture optimiste StampedLock sl= new StampedLock() ; long stamp = sl.tryOptimisticRead() ; // ici on lit une variable qui peut être modifiée par un autre thread if (lock.validate(stamp)) { // la lecture est validée } else { // un autre thread a acquis un write lock }
  90. 90. ConcurrentConcurrent HashMap
  91. 91. @JosePaumard#50new8 ConcurrentHashMap Réécriture complète de ConcurrentHashMap V7 Complètement thread-safe N’utilise de lock ≠ ConcurrentHashMap V7 Nouvelles méthodes
  92. 92. @JosePaumard#50new8 ConcurrentHashMap 6000 lignes de code
  93. 93. @JosePaumard#50new8 ConcurrentHashMap 6000 lignes de code 54 classes membre
  94. 94. @JosePaumard#50new8 ConcurrentHashMap 6000 lignes de code 54 classes membre Pour info : 58 classes dans java.util.concurrent
  95. 95. @JosePaumard#50new8 ConcurrentHashMap 6000 lignes de code 54 classes membre Pour info : 58 classes dans java.util.concurrent Nouveaux patterns !
  96. 96. @JosePaumard#50new8 ConcurrentHashMap Ne plus utiliser size() int count = map.size() ; // ne pas utiliser count = map.mappingCount() ; // nouvelle méthode
  97. 97. @JosePaumard#50new8 ConcurrentHashMap Ne plus utiliser int count = map.size() ; // ne pas utiliser long count = map.mappingCount() ; // nouvelle méthode
  98. 98. @JosePaumard#50new8 ConcurrentHashMap Recherche d’éléments search(), searchKey(), searchValue(), searchEntry() ConcurrentHashMap<Integer, String> map = ... ; map.search(10, (key, value) -> value.length() < key) ;
  99. 99. @JosePaumard#50new8 ConcurrentHashMap Recherche d’éléments search(), searchKey(), searchValue(), searchEntry() ConcurrentHashMap<Integer, String> map = ... ; map.search(10, (key, value) -> value.length() < key) ;
  100. 100. @JosePaumard#50new8 ConcurrentHashMap Recherche d’éléments 10 : taux de parallélisme Si la table compte plus de 10 éléments, alors la recherche se fait en parallèle ! ConcurrentHashMap<Integer, String> map = ... ; map.search(10, (key, value) -> value.length() < key) ;
  101. 101. @JosePaumard#50new8 ConcurrentHashMap Recherche d’éléments 10 : taux de parallélisme Si la table compte plus de 10 éléments, alors la recherche se fait en parallèle ! On peut passer 0, ou Integer.MAX_VALUE ConcurrentHashMap<Integer, String> map = ... ; map.search(10, (key, value) -> value.length() < key) ;
  102. 102. @JosePaumard#50new8 ConcurrentHashMap ForEach forEach(), forEachKey(), forEachEntries() ConcurrentHashMap<Integer, String> map = ... ; map.forEach(10, (key, value) -> System.out.println(String.join(key, "->", value) ) ;
  103. 103. @JosePaumard#50new8 ConcurrentHashMap Réduction reduce(), reduceKey(), reduceEntries() ConcurrentHashMap<Integer, String> map = ... ; map.reduce(10, (key, value) -> value.getName(), // transformation (name1, name2) -> name1.length() > name2.length() ? name1 : name2) // reduction ) ;
  104. 104. @JosePaumard#50new8 Pas de ConcurrentHashSet Mais… Set<String> set = ConcurrentHashMap.<String>.newKeySet() ;
  105. 105. @JosePaumard#50new8 Pas de ConcurrentHashSet Mais… Crée une concurrent hashmap dont les valeurs sont Boolean.TRUE Sert de set concurrent Set<String> set = ConcurrentHashMap.<String>.newKeySet() ;
  106. 106. @JosePaumard #50new8

×