SlideShare une entreprise Scribd logo
1  sur  59
Télécharger pour lire hors ligne
1
les nouveautés de Java
19, 20 et 21
@jmdoudoux
JMdoudouX
11 juillet 2023
Sciam
Java 19, 20 et 21
2
Java poursuit son évolution
En respectant le rythme de release tous les 6 mois
Java 19 Java 20 Java 21
Publication 20 / 09 / 2022 21 / 03 / 2023 19 / 09 / 2023
Spécification JSR 394 JSR 395 JSR 396
Implémentation de
référence
OpenJDK 19 OpenJDK 20 OpenJDK 21
Durée des patchs 6 mois 6 mois > 2 ans
Nb JEPs 7 7 15
JDK 21 est une version LTS
Depuis la réduction de 3 à 2 ans entre 2 LTS après Java 17
Sciam
Les JEPs de Java 19, 20 et 21
Java 19 et 20
3
JEP 440 : Record Patterns
JEP 442 : Foreign Function & Memory API (Third Preview)
JEP 444 : Virtual Threads
JEP 441 : Pattern Matching for switch
JEP 448 : Vector API (Sixth Incubator)
JEP 453 : Structured Concurrency (Preview)
JEP 446 : Scoped Values (Preview)
JEP 430 : String Templates (Preview)
JEP 431 : Sequenced Collections
JEP 439 : Generational ZGC
JEP 443 : Unnamed Patterns and Variables (Preview)
JEP 445 : Unnamed Classes and Instance Main Methods (Preview)
JEP 449 : Deprecate the Windows 32-bit x86 Port for Removal
JEP 451 : Prepare to Disallow the Dynamic Loading of Agents
JEP 452 : Key Encapsulation Mechanism API
Java 21
JEP 405 et 432 : Record Patterns (Preview)
JEP 424 et 434 : Foreign Function & Memory API (Preview)
JEP 425 et 436 : Virtual Threads (Preview)
JEP 427 et 433 : Pattern Matching for switch (Preview)
JEP 426 et 438 : Vector API (Incubator)
JEP 428 et 437 : Structured Concurrency (Incubator)
JEP 429 : Scoped Values (Incubator)
JEP 422 : Linux/RISC-V Port
Sciam 4
Jean-Michel Doudoux
https://www.jmdoudoux.fr
@jmdoudoux
Co-fondateur du
Auteur de 2 didacticiels
Diffusés sous licence GNU FDL
• Développons en Java (4000 pages)
• Développons en Java avec Eclipse
Senior Tech Lead
chez
Sciam
Roadmap
Les fonctionnalités
du projet Amber
5
Les évolutions
du projet Loom
dans la JVM Hotspot
dans les API Java Core
Les fonctionnalités du projet Panama
Sciam
Les fonctionnalités du
projet Amber
Record Patterns
Pattern Matching for switch
String Templates (Preview)
Unnamed Patterns and Variables (Preview)
Unnamed Classes and Instance Main Methods (Preview)
Sciam
Record Patterns
En preview en Java 19 (JEP 420) et 20 (JEP 432)
7
Standard en Java 21
Type pattern utilisable avec le pattern matching sur les records
record Employe(String nom, String prenom) {}
Object o = new Employe("Nom1", "Prenom1");
if (o instanceof Employe emp) {
System.out.println("Employe : "+emp.nom()+" "+emp.prenom());
}
Ajouter un nouveau pattern utilisable dans le pattern matching
Le record pattern pour déconstruire les valeurs d’un record
if (o instanceof Employe(String nom, String prenom)) {
System.out.println("Employe : "+nom+" "+prenom);
}
Sciam
switch (o) {
case Employe emp -> System.out.println(emp);
case Grade(String code,String designation) -> System.out.println("Grade " + designation + "(" + code + ")");
default -> System.out.println("Type non supporté");
}
Record Patterns
Utilisable avec une instruction instanceof ou switch
Type pattern et record pattern peuvent être combinés
Dans un même switch
Java 20 : utilisable dans une boucle for améliorée
List<Employe> employes = List.of(new Employe("Nom1", "Prenom1"));
for(Employe(var nom, var prenom) : employes) {
System.out.println(nom + " " + prenom);
}
8
Java 21 : retiré
Sciam
Record Patterns
Le nom des variables peut être différents de celui des composants
Seuls l’ordre et le type des composants doivent être respectés
if (o instanceof Employe(String n, String p)) {
System.out.println("Employe : " + n + " " + p);
}
if (o instanceof Employe(var nom, var prenom)) {
System.out.println("Employe : "+nom+" "+prenom);
}
Utilisation possible de l’inférence du type dans le pattern
9
record Mono<T>(T val) implements Container<T> {}
Mono<Mono<String>> monoDeMono = new Mono<>(new Mono<>("valeur"));
Java 20 : support de l'inférence des types d’arguments génériques
if (monoDeMono instanceof Mono(Mono(var s))) {
System.out.println("mono contient " + s);
}
Sciam
record Grade(String code, String designation) {}
record Employe(String nom, String prenom, Grade grade) {}
Object o = new Employe("Nom1", "Prenom1", new Grade("DEV", "Développeur"));
if (o instanceof Employe(var nom, var prenom, Grade(var code, var designation))) {
System.out.println("Employe : " + nom + " " + prenom + ", "+ designation);
}
Record Patterns
Les record patterns peuvent être imbriqués
La valeur null ne correspond à aucun record pattern
10
Sciam
Pattern Matching for switch
Historiquement 4 preview en Java
17 (JEP 406), 18 (JEP 420), 19 (JEP 427) et 20 (JEP 433)
But : utiliser le pattern matching dans une instruction switch
En maintenant la compatibilité syntaxique
Avec un support de la valeur null contrairement à la levée historique d’une NPE
11
static String getDesignation(Object obj) {
String designation = switch (obj) {
case Terrain t -> "Terrain";
case null -> "Instance null";
default -> "Pas un terrain";
};
return designation;
}
Standard en Java 21
Plusieurs patterns utilisables
Type pattern
Teste la correspondance sur un type
Sciam
Pattern Matching for switch
Record Pattern
Déconstruit un record
Utilise le nouveau mot clé contextuel when
12
static String getDesignation(Object obj) {
String designation = switch (obj) {
case Terrain t
when (t.getSurface() > 1000) -> "Grand terrain";
case Terrain t -> "Petit terrain";
case null -> "Instance null";
default -> "Pas un terrain";
};
return designation;
}
Utilisation possible d’un Guarded pattern case label
Combine un pattern et une expression booléenne dans un case
Parenthesized pattern retiré en Java 21
Sciam
Pattern Matching for switch
Possibilité de mixer constantes et patterns
13
L’exhaustivité des cas d’un switch doit être satisfaite
Sinon erreur de compilation : implique fréquemment l’utilisation d’un default
Au runtime une exception de type java.lang.MatchException est levée
Exemple : sur un type scellé ou une énumération par exemple
String getEnv(String env) {
return switch (env) {
case "Prod" -> "Production";
case String s -> "Hors production";
};
}
static String formater(Number nombre) {
return switch (nombre) { // erreur : the switch expression does not cover all possible input values
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
}; }
Sciam
Pattern Matching for switch
Le compilateur vérifie la dominance des patterns
Les patterns les plus restrictifs doivent être avant les moins restrictifs
14
static String formater(Object o) {
return switch (o) {
case Number n -> String.format("number %f", n);
case Integer i -> String.format("int %d", i); // erreur this case label is dominated by a preceding case label
case Long l -> String.format("long %d", l);
default -> o.toString();
};
}
Idem avec les guarded patterns case label
String taille = switch (chaine) {
case String s -> "Moyenne";
case String s when s.length() < 10 -> "Petite"; // erreur this case label is dominated by a preceding case label
case String s when s.length() > 100 -> "Grande";
};
Sciam
Pattern Matching for switch
Sémantique d'exécution d’un switch avec le pattern matching
Lorsque la valeur est null et que le cas null n’est pas explicitement géré :
Elle est étroitement alignée sur la sémantique historique des switchs
15
public static void main(String[] args) {
String chaine = null;
switch (chaine) {
case String s -> {
System.out.println("traitement chaine");
System.out.println("taille : " + s.length());
}
}
}
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:233)
at TestSwitchPattern.main(TestSwitchPattern.java:5)
Sciam
Java 21 autorise les constantes d'énumération qualifiées
Dans les cases des switchs afin d’éviter d’avoir à utiliser un guarded pattern case label
16
public sealed interface MonInterface permits MonEnum, MaClasse {}
public enum MonEnum implements MonInterface { PAIRE, IMPAIRE }
public final class MaClasse implements MonInterface {}
// …
static void traiter(MonInterface c) {
switch (c) {
// case MonEnum e when e == MonEnum.PAIRE -> { System.out.println("Paire"); }
case MonEnum.PAIRE -> { System.out.println("Paire"); }
case MonEnum.IMPAIRE -> { System.out.println("Impaire"); }
case MonEnum e -> { System.out.println("MonEnum"); }
case MaClasse mc -> { System.out.println("MaClasse"); }
}
}
Pattern Matching for switch
Sciam
String Templates (Preview)
Courant de devoir créer des chaînes de caractères composées
À partir d'une combinaison de textes littéraux
Et de valeurs ou d'expressions
17
Historiquement plusieurs fonctionnalités, toutes avec inconvénients
String s = x + " + " + y + " = " + (x + y);
MessageFormat mf = new MessageFormat("{0} + {1} = {2}");
String s = mf.format(x, y, x + y);
String s = String.format("%2$d + %1$d = %3$d", x, y, x + y);
String t = "%2$d + %1$d = %3$d".formatted(x, y, x + y);
String s = new StringBuilder()
.append(x)
.append(" + ")
.append(y)
.append(" = ")
.append(x + y)
.toString();
De nombreux langages proposent l'interpolation de chaînes
Comme alternative à la concaténation de chaînes
Sciam
String Templates (Preview)
La plupart des langages supportent l’interpolation de chaînes
Mais le résultat peut parfois engendrer des soucis indirects
Exemple : SQL ou JSON injection
18
En combinant :
- Un texte littéral avec des expressions intégrées
- Et un processeur de templates
Pour produire des chaînes de caractères construites dynamiquement
Avec la clarté de l’interpolation et un résultat plus sûr
Le but : enrichir le langage Java avec des string templates
Qui complètent les chaînes littérales et les blocs de texte
Possibilité de créer une instance de type quelconque
Avec un processeur de templates personnalisés
Sciam
String Templates (Preview)
Nouveau type d'expression dans le langage : les templates expressions
Pour effectuer une interpolation de chaîne pour créer une chaîne ou un objet
19
Syntaxiquement, ressemble à une chaîne littérale avec un préfixe :
String prenom = "Jean-Michel";
String message = STR."Bonjour {prenom}";
Une template expression est composée de trois éléments :
1) Un processeur de templates (STR)
2) Un caractère point (U+002E), celui utilisé dans les autres expressions
3) Un template ("Bonjour {prenom}")
qui contient une expression intégrée ({prenom})
Le template peut utiliser plusieurs lignes de code source
En utilisant une syntaxe similaire à celle des blocs de texte
Sciam
String Templates (Preview)
3 processeurs de templates dans le JDK
20
STR : effectue une interpolation pour créer une chaîne
int x = 10, y = 20;
String s = STR."{x} + {y} = {x + y}";
FMT : effectue une interpolation pour créer une chaîne
Il interprète les spécificateurs de format à gauche des expressions intégrées
Les spécificateurs de format sont ceux définis dans java.util.Formatter
RAW : produit un objet de type StringTemplate
String prenom = "Jean-Michel";
StringTemplate st = RAW."Bonjour {prenom}";
String message = STR.process(st);
Sciam
String Templates (Preview)
Possibilité de définir des processeurs de templates personnalisés
Pour générer des chaînes ou des objets qui peuvent être validés
21
Une instance de l'interface fonctionnelle StringTemplate.Processor
Implémenter l’unique méthode process()
Utilisation de la fabrique StringTemplate.Processor::of
Pour obtenir une instance
var JSON = StringTemplate.Processor.of((StringTemplate st) -> new JSONObject(st.interpolate()));
String nom = "Durant";
String prenom = "Pierre";
JSONObject doc = JSON."""
{
"nom": "{nom}",
"prenom": "{prenom}"
}""";
Sciam
Unnamed Patterns and Variables (Preview)
Enrichit le langage d’une syntaxe
Pour les patterns inutilisés dans les records pattern imbriqués
Et les variables inutilisées qui doivent être déclarées
22
Unnamed pattern : un pattern inconditionnel qui ne correspond à rien
Utilisable dans un pattern imbriqué à la place d'un type ou record pattern
record Grade(String code, String designation) {}
record Employe(String nom, String prenom, Grade grade) {}
Object o = new Employe("Nom1", "Prenom1", new Grade("DEV", "Développeur"));
if (o instanceof Employe(var nom, var prenom, _)) {
System.out.println("Employe : " + nom + " " + prenom);
}
Utilisant le 51eme mot clé réservé de Java : _
Sciam
Unnamed Patterns and Variables (Preview)
Unnamed pattern variable :
Utilisable avec tous types de patterns
23
Unnamed variable : peut être initialisée mais non utilisée dans
Une variable locale dans un bloc
Une ressource dans un try-with-resources
L'en-tête d'une boucle for et for améliorée
Une exception d'un bloc catch
Un paramètre formel d'une expression Lambda
try (var _ = ScopedContext.acquire()) {
var _ = service.traiter((_, _) -> System.out.printn("traiter"));
} catch (Throwable _) { }
if (o instanceof Employe(var nom, var _, _)) {
System.out.println("Employe : " + nom);
}
Utilisable plusieurs fois dans la même portée
Sciam
Unnamed Patterns and Variables (Preview)
Utile dans des switchs avec des patterns sur des types scellés
24
void traiterFormeRonde(Forme forme) {
switch(forme) {
case Cercle c -> afficher(c);
case Carre c -> {}
case Rectangle r -> {}
}
}
switch(forme) {
case Cercle c -> afficher(c);
default -> {}
}
switch(forme) {
case Cercle c -> afficher(c);
case Carre _, Rectangle _ -> {}
}
Impossible d’avoir plusieurs patterns
nommés dans un case
Risque de bug en cas d’ajout d’un type :
sealed interface Forme permits Cercle, Carre, Rectangle {}
Utilisation possible de default
préférable d’utiliser des unnamed variables
Sciam
Unnamed Classes and Instance Main Methods (Preview)
25
Plutôt compliqué
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
Les buts :
Faire évoluer le langage pour simplifier les programmes simples
Et faciliter l’apprentissage des débutants avec le langage Java
Méthode d’instance main()
class HelloWorld {
void main() {
System.out.println("Hello world");
}
}
void main() {
System.out.println("Hello world");
}
Classe sans nom (unnamed class)
Deux évolutions dans une classe unique
Sciam
Les fonctionnalités du projet
Loom
Virtual Threads
Structured Concurrency (Preview)
Scoped Values (Preview)
Sciam
Virtual Threads
Chaque thread Java est directement mappé à un thread de l’OS
Depuis Java 1.0
Ce modèle n’est pas optimal
Car un thread de la plateforme est coûteux en ressources
Notamment à cause de la taille fixe (par défaut) de sa pile
27
Cela limite le nombre de threads qui peuvent être utilisés
Décharge la JVM de se préoccuper de tâches réalisées par l’OS
Ordonnancement et changement de contexte des threads
Or on utilise de plus en plus de threads
Qui généralement passent beaucoup de temps à attendre la fin d’une opération bloquante
Sciam
Virtual Threads
Introduction d’un nouveau type de threads : des threads virtuels
Plusieurs objectifs :
28
Ce sont des threads « légers » gérés dans la JVM
Non lié à un thread de la plate-forme dédié
Qu’il utilise uniquement lors de l’utilisation de la CPU par ses traitements
• Assurer une adoption par le code existant
Qui utilise l'API java.lang.Thread avec un impact minimum
• Conserver le style « un thread par requête »
Avec une meilleure utilisation des ressources requises
• Permettre le débogage, le profilage et le dépannage
Avec les outils existants du JDK
En preview Java 19 (JEP 425) et 20 (JEP 436)
En standard Java 21 (JEP 444)
Sciam
Virtual Threads
Exécutent du code qui ne bloque pas les threads de l’OS
Contrairement aux verrous ou aux opérations bloquantes (I/O par exemple)
Si le thread virtuel exécute une action bloquante dans les API du JDK
La JVM enregistrement la stack dans le heap et exécute l’action en non bloquante
29
Le thread porteur peut alors exécuter un autre thread virtuel
Mapping M:N entre threads virtuels et threads de l’OS
Grâce à un ForkJoinPool dédié qui fournit les threads porteurs (carrier threads)
Une fois l’action non bloquante terminée
L’exécution des traitements du thread virtuel est reprise sur un thread porteur
Potentiellement différent
Ce mécanisme est géré en interne par les API du JDK
En utilisant des objets de type Continuation et ContinuationScope
Et est transparent pour le développeur
Sciam
Virtual Threads
La classe finale package-private java.lang.VirtualThread
Hérite de java.lang.Thread
Pas de constructeur public
L’interface scellée Thread.Buidler propose deux interfaces filles
Thread.Builder.OfVirtual et Thread.Builder.OfPlatform
Dont on obtient une instance avec Thread::ofVirtual et Thread::ofPlatform
30
Le plus simple est d’utiliser Thread::startVirtualThread
Pour démarrer un nouveau thread virtuel qui exécute un Runnable
Thread t = Thread.startVirtualThread(() -> {
System.out.println("Thread : " + Thread.currentThread());
});
var threadVirtuel = Thread.ofVirtual().name("app-thread-virtuel-", 0).start(() -> {
System.out.println(Thread.currentThread());
});
threadVirtuel.join();
Sciam
Virtual Threads
Plusieurs restrictions sur les threads virtuels :
31
• Ils sont obligatoirement des threads démons
• stop(), resume(), suspend() lèvent une UnsupportedOperationException
• La priorité est obligatoirement Thread.NORM_PRIORITY
• Ils ne peuvent pas être associés à un ThreadGroup
• getThreadGroup() renvoie un groupe "VirtualThreads" fictif qui est vide
• getAllStackTraces() renvoie une Map qui contient uniquement que les threads de l’OS
plutôt que de tous les threads
Ne pas mettre les threads virtuels dans un pool
Aucune utilité vue leur faible coût de création
Sciam
Virtual Threads
Peuvent améliorer le débit des applications
Lorsque le nombre de tâches simultanées est important
Et que les tâches ne requièrent pas de manière intensive la CPU
32
Deux scénarios bloquants peuvent limiter l’intérêt des threads virtuels
Car ils laissent le thread virtuel associé à son thread porteur
• L’exécution d’un bloc de code synchronized
Il est préférable d’utiliser si possible un ReentrantLock
• Lors de l’exécution d’une méthode native
Option de la JVM pour identifier ces cas
Un événement JFR : jdk.VirtualThreadPinned
-Djdk.tracePinnedThreads=full ou short
Sciam
Structured Concurrency (preview)
Propose un nouveau modèle de programmation
Grâce au traitement de plusieurs tâches
Exécutées dans différents threads virtuels comme une seule unité de travail
33
Fork/Join et concurrence structurée sont complémentaires
Le but : simplifier la programmation multithread
En rationalisant la gestion des erreurs et l'annulation,
En améliorant la fiabilité et en renforçant l'observabilité
Fork/Join
Conçu pour traiter des tâches à forte intensité
de calcul sur une courte durée
Utilise des threads de l’OS
Complexe à mettre œuvre
Concurrence structurée
Conçue pour traiter des tâches à forte intensité
d'E/S
Utilise des threads virtuels
Facile à mettre en oeuvre
Sciam
Structured Concurrency (preview)
API en incubation en Java 20
Classe principale : java.util.concurrent.StructuredTaskScope
34
Le modèle permet une écriture du code dans un style synchrone
Avec une exécution en asynchrone
Le code est ainsi facile à écrire, à lire et à tester
API en preview en Java 21
Dans le package java.util.concurrent
Sciam
Structured Concurrency (preview)
La mise en œuvre en plusieurs étapes
35
• Créer une instance dans un try-with-resource
Facture getFacture(String codeClient, long idCommande) throws ExecutionException, InterruptedException, TimeoutException {
Facture resultat = null;
try (var scope = new StructuredTaskScope()) {
Subtask<Client> clientFuture = scope.fork(() -> this.getClient(codeClient));
Subtask <Commande> commandeFuture = scope.fork(() -> this.getCommande(idCommande));
scope.joinUntil(Instant.now().plusSeconds(15));
resultat = this.genererFacture(clientFuture.get(), commandeFuture.get());
}
return resultat;
}
• Invoquer la méthode fork() pour chaque sous-tâche à exécuter
• Attendre la fin de l’exécution des sous-tâches
o Soit sans timeout en utilisant la méthode join()
o Soit avec timeout en utilisant la méthode joinUntil()
• Exploiter les résultats obtenus dans des instances de type Subtask (Future en Java 20)
Sciam
Structured Concurrency (preview)
La classe StructuredTaskScope.ShutdownOnFailure
Propose un modèle invoke all
36
Facture getFacture(String codeClient, long idCommande)
throws ExecutionException, InterruptedException, TimeoutException {
Facture resultat = null;
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Subtask <Client> clientFuture = scope.fork(() -> this.getClient(codeClient));
Subtask<Commande> commandeFuture = scope.fork(() -> this.getCommande(idCommande));
scope.joinUntil(Instant.now().plusSeconds(15));
scope.throwIfFailed();
resultat = this.genererFacture(clientFuture.get(), commandeFuture.get());
}
return resultat;
}
Qui exécute toutes les sous-tâches
Et termine toutes les sous-tâches en cours si une sous-tâche lève une exception
Sciam
Structured Concurrency (preview)
La classe StructuredTaskScope.ShutdownOnSuccess
Propose un modèle invoke any
37
Temperature getTemperature(String ville) throws InterruptedException, ExecutionException {
Temperature resultat = null;
try (var scope = new StructuredTaskScope.ShutdownOnSuccess<Temperature>()) {
serviceMeteos.forEach(f -> {
scope.fork(() -> f.getTemperature(ville));
}
);
scope.join();
resultat = scope.result();
}
return resultat;
}
Qui renvoie le résultat de la première sous-tâche terminée
Et termine les autres sous-tâches restantes
Sciam
Structured Concurrency (preview)
Possibilité de créer son propre scope
En héritant de la classe StructuredTaskScope
Et en y implémentant ses propres règles métiers
38
class ComposantLePlusLegerScope extends StructuredTaskScope<Composant> {
private final Collection<Composant> composants = new ConcurrentLinkedQueue<>();
private final Collection<Throwable> exceptions = new ConcurrentLinkedQueue<>();
@Override
protected void handleComplete(Subtask<? extends Composant> subtask) {
switch (subtask.state()) {
case SUCCESS -> this.composants.add(subtask.get());
case FAILED -> this.exceptions.add(subtask.exception());
case UNAVAILABLE -> {}
}
}
Sciam
Structured Concurrency (preview)
39
public Exception exceptions() {
RuntimeException exception = new RuntimeException("Impossible d'obtenir le composant le plus leger");
exceptions.forEach(exception::addSuppressed);
return exception;
}
public Composant getComposant() throws Exception {
return composants.stream().min(Comparator.comparing(Composant::poids))
.orElseThrow(this::exceptions);
}
}
Sciam
Scoped Values (Preview)
Pour partager des objets dans le code exécuté par un thread
Historiquement depuis Java 1.2, on utilise une variable de type ThreadLocal
L’API ScopedValue tente de remédier à ces inconvénients
40
Mais cela présente plusieurs risques :
Mutable, fuite de mémoire, consommation de ressources
public final static ScopedValue<String> VALEUR = ScopedValue.newInstance();
Création d’une instance généralement statique et publique
Stocker et de partager des données immuables
Pour une durée de vie limitée à des traitements du thread qui les a écrits
En incubation dans Java 20 (JEP 429)
En preview dans Java 21 (JEP 446)
Sciam
Scoped Values (Preview)
where() pour définir une valeur, chainable pour plusieurs valeurs
get() pour obtenir la valeur ou lève une NoSuchElementException
41
Pour exécuter une tâche dans le thread courant
System.out.println((VALEUR.isBound() ? VALEUR.get() : "non definie"));
isBound() pour savoir si une valeur est associée au thread
run() : sous la forme d’une implémentation de Runnable
ScopedValue.where(VALEUR, "test").run(() -> { afficherValeur(); });
Ou call() : sous la forme d’une implémentation de Callable
String valeur = ScopedValue.where(VALEUR, "test")
.<String>call(monService::traiter);
Sciam
Scoped Values (Preview)
Réassociation d’une valeur pour un traitement sous-jacent
Partage avec les threads virtuels d’une StucturedTaskScope
42
ScopedValue.where(VALEUR, "valeur", () -> {
try (var scope = new StructuredTaskScope<String>()) {
afficherValeur();
scope.fork(monServiceA::traiter);
scope.fork(monServiceB::traiter);
scope.joinUntil(Instant.now().plusSeconds(10));
} catch (InterruptedException | TimeoutException e) {
e.printStackTrace();
}
});
ScopedValue.where(VALEUR, "valeur").run(() -> {
afficherValeur(); // valeur
ScopedValue.where(VALEUR, "autre-valeur").run(monService::traiter); // autre-valeur
afficherValeur(); // valeur
});
Sciam
Les évolutions
dans les API de Java Core
Sequenced Collections
Sciam
Sequenced collections
L’API Collections propose des collections ordonnées
Mais n’est pas homogène dans les fonctionnalités proposées
44
Les opérations liées à l'ordre de parcours sont soit incohérentes soit absentes
Premier élément Dernier élément
List list.get(0) list.get(list.size() - 1)
Deque deque.getFirst() deque.getLast()
SortedSet sortedSet.first() sortedSet.last()
LinkedHashSet linkedHashSet.iterator().next()
Des implémentations permettent d'obtenir le premier ou le dernier élément
Chacune avec leurs méthodes, dont certaines pas évidentes ou inexistantes
Idem pour le parcours dans l’ordre inverse
Sciam
Sequenced collections
Introduire 3 nouvelles interfaces
Pour représenter des collections avec un ordre de parcours défini
45
Elles possèdent :
Des éléments parcourables du premier au dernier élément dans un certain ordre
Fournissent des API uniformes pour accéder au 1er et dernier élément
Et pour parcourir ses éléments dans l'ordre inverse
SequencedSet
SequencedCollection
SequencedMap
Sciam
Sequenced collections
46
Sciam
Les évolutions
dans la JVM HotSpot
Linux/RISC-V Port
Generational ZGC
Deprecate the Windows 32-bit x86 Port for Removal
Prepare to Disallow the Dynamic Loading of Agents
Sciam
Linux/RISC-V Port
RISC-V est une architecture de jeu d'instructions (ISA) RISC libre et gratuite
Conçu à l'origine à l'Université Berkeley de Californie
Maintenant développé collaborativement sous le parrainage de RISC-V International
De nombreux acteurs envisagent son utilisant notamment :
Apple, la NASA, de nombreux industriels asiatiques notamment chinois et indiens
48
Anticipe cela avec le portage d’OpenJDK sur Linux/RISC-V
Qui est intégré au repository principal dans Java 19
Peu d’appareil grand public utilisant RISC-V actuellement
Mais cela risque de changer dans un futur proche
Sciam
Generational ZGC
Rendre le ramasse-miettes ZGC générationnel
49
Tout en maintenant les caractéristiques actuelles
Activation avec les options :
-XX:+UseZGC -XX:+ZGenerational
Les tailles de tas allant de quelques centaines de Mo à 16 To
Les temps de pause ne doivent pas dépasser 1 milliseconde
ZGC générationnel devrait être une meilleure solution
Pour la plupart des cas d'utilisation que le ZGC non générationnel
Sciam
Les fonctionnalités du
projet Panama
Foreign Function & Memory API (Third Preview)
Vector API (Sixth Incubator)
Sciam
Foreign Function & Memory API (Third Preview)
API de bas niveau pour de manière simple, sûre et efficace :
• Accéder à des données en mémoire hors du tas (off heap memory)
• Invoquer des fonctions natives
Proposée en preview en Java 19 (JEP 424), 20 (JEP 434) et 21 (JEP 442)
Elle est maintenant dans le module java.base
51
Historiquement, fusion de 2 JEPs introduites en incubation :
Foreign-Memory Access API en Java 14 (JEP 370, 383, et 393)
Et Foreign Linker API en Java 16 (JEP 389)
Proposée en incubation en Java 17 (JEP 412) et Java 18 (JEP 419)
Attention : cette API évolue beaucoup
Dans chacune des versions de Java où elle est proposée
Sciam
L’API de bas niveau
2) Pour invoquer du code natif
Une future alternative à l’API JNI présente depuis Java 1.1
52
1) Pour accéder à des données
En mémoire hors du tas (off heap memory)
De manière sûre et performante
Alternative à certaines fonctionnalités
De java.nio.ByteBuffer (pas performante mais sûre)
Et sun.misc.Unsafe (non standard)
Foreign Function & Memory API (Third Preview)
Sciam
public class DialogFFM {
public static void main(String[] args) {
try {
System.loadLibrary("user32");
Optional<MemorySegment> msgBoxFunction = SymbolLookup.loaderLookup().find("MessageBoxA");
FunctionDescriptor msgBoxFunctionDesc = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS, ADDRESS, JAVA_INT);
Linker linker = Linker.nativeLinker();
MethodHandle methodHandle = linker.downcallHandle(msgBoxFunction.get(), msgBoxFunctionDesc);
try (Arena offHeap = Arena.ofConfined()) {
MemorySegment cStringMessage = offHeap.allocateUtf8String("Voulez-vous utiliser Java 21 ?");
MemorySegment cStringTitre = offHeap.allocateUtf8String("Confirmation");
int bouton = (int) methodHandle.invoke(NULL, cStringMessage, cStringTitre, 36);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
53
Foreign Function & Memory API (Third Preview)
Exemple Java 21 sous Windows
Sciam
Vector API (Sixth Incubator)
Exprimer des calculs vectoriels
Qui, au moment de l'exécution, sont systématiquement compilés
Avec les meilleures instructions vectorielles possibles sur l’architectures CPU
Les SIMD sur les CPU supportées : x64 (SSE et AVX) et AArch64 (Neon)
Dans le module jdk.incubator.vector
54
Single Instruction, Multiple Data
Traiter en parallèle un tableau de données, sans threads
Pour appliquer une même opération sur plusieurs valeurs traitées
En un seul cycle de traitement CPU
En incubation en Java 16 (JEP 338), 17 (JEP 414), 18 (JEP 417),
19 (JEP 426), 20 (JEP 438) et 21 (JEP 448)
Sciam
static float[] calculerScalaire(float[] a, float[] b) {
float[] c = new float[a.length];
for (int i = 0 ; i < a.length ; i++) {
c[i] = a[i] * a[i] - b[i] * b[i];
}
return c;
}
55
API plutôt de bas niveau, verbeuse, dépendant partiellement du CPU
Mais qui peut offrir de meilleures performances que le code scalaire équivalent
Exemple Java 21
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
static float[] calculerVectoriel(float[] a, float[] b) {
float[] c = new float[a.length];
int i = 0;
for (; i < SPECIES.loopBound(a.length) ; i += SPECIES.length()) {
var va = FloatVector.fromArray(SPECIES, a, i);
var vb = FloatVector.fromArray(SPECIES, b, i);
var vr = va.mul(va).sub(vb.mul(vb));
vr.intoArray(c, i);
}
for (; i < a.length; i++) {
c[i] = a[i] * a[i] - b[i] * b[i];
}
return c;
}
Vector API (Sixth Incubator)
Sciam
Conclusion
Sciam
Conclusion
Java poursuit son évolution en respectant son modèle de releases
La syntaxe, particulièrement le pattern matching
57
Java 21 proposent des fonctionnalités concernant
Cela permettra à Java de rester pertinent aujourd’hui et demain
La programmation parallèle et concurrente
Une meilleure utilisation du matériel moderne
N’hésitez pas à télécharger l’Early Access : https://jdk.java.net/21/
Java 21, le 19 septembre 2023
Pour anticiper la release de la prochaine version LTS du JDK
Sciam
Merci pour votre attention
Sciam

Contenu connexe

Tendances (20)

API
APIAPI
API
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Service workers
Service workersService workers
Service workers
 
Angular Observables & RxJS Introduction
Angular Observables & RxJS IntroductionAngular Observables & RxJS Introduction
Angular Observables & RxJS Introduction
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
REST API
REST APIREST API
REST API
 
Exception handling
Exception handlingException handling
Exception handling
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Web API Basics
Web API BasicsWeb API Basics
Web API Basics
 
Solid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSSolid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJS
 
Rest api standards and best practices
Rest api standards and best practicesRest api standards and best practices
Rest api standards and best practices
 
Introduction à Angular
Introduction à AngularIntroduction à Angular
Introduction à Angular
 
Rxjs ppt
Rxjs pptRxjs ppt
Rxjs ppt
 
Spring Security
Spring SecuritySpring Security
Spring Security
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Springboot Microservices
Springboot MicroservicesSpringboot Microservices
Springboot Microservices
 
Angular
AngularAngular
Angular
 
Loom promises: be there!
Loom promises: be there!Loom promises: be there!
Loom promises: be there!
 

Similaire à Les nouveautés de Java 19, 20 et 21 - RivieraDev 2023

En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023Jean-Michel Doudoux
 
Les nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdf
Les nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdfLes nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdf
Les nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdfJean-Michel Doudoux
 
Les nouveautés de Java 21 - Devoxx MA 2023.pdf
Les nouveautés de Java 21 - Devoxx MA 2023.pdfLes nouveautés de Java 21 - Devoxx MA 2023.pdf
Les nouveautés de Java 21 - Devoxx MA 2023.pdfJean-Michel Doudoux
 
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Jean-Michel Doudoux
 
Présentation de ECMAScript 6
Présentation de ECMAScript 6Présentation de ECMAScript 6
Présentation de ECMAScript 6Julien CROUZET
 
Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5Mamadou Oury Ba
 
Java 5, un blian
Java 5, un blianJava 5, un blian
Java 5, un bliantareq
 
Java 5, un bilan
Java 5,  un bilanJava 5,  un bilan
Java 5, un bilanteejug
 
Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Dr Samir A. ROUABHI
 
Librairies Java qui changent la vie
Librairies Java qui changent la vieLibrairies Java qui changent la vie
Librairies Java qui changent la viecluelessjoe
 
Chapitre 2: String en Java
Chapitre 2:  String en JavaChapitre 2:  String en Java
Chapitre 2: String en JavaAziz Darouichi
 
Javascript Json artchitecture
Javascript  Json artchitecture Javascript  Json artchitecture
Javascript Json artchitecture zaghir
 
Eric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharpEric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharpMSDEVMTL
 
Développement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresDéveloppement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresECAM Brussels Engineering School
 
Introduction java
Introduction javaIntroduction java
Introduction javaFouad Root
 
Introduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniIntroduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniShellmates
 

Similaire à Les nouveautés de Java 19, 20 et 21 - RivieraDev 2023 (20)

En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023
 
Les nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdf
Les nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdfLes nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdf
Les nouveautés de Java 21 - Rencontres dev Toulon octobre 2023.pdf
 
Les nouveautés de Java 21 - Devoxx MA 2023.pdf
Les nouveautés de Java 21 - Devoxx MA 2023.pdfLes nouveautés de Java 21 - Devoxx MA 2023.pdf
Les nouveautés de Java 21 - Devoxx MA 2023.pdf
 
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20
 
Présentation de ECMAScript 6
Présentation de ECMAScript 6Présentation de ECMAScript 6
Présentation de ECMAScript 6
 
Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5
 
JAVA
JAVAJAVA
JAVA
 
Java 5, un blian
Java 5, un blianJava 5, un blian
Java 5, un blian
 
Java 5, un bilan
Java 5,  un bilanJava 5,  un bilan
Java 5, un bilan
 
Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)
 
Change mind about JS
Change mind about JSChange mind about JS
Change mind about JS
 
Librairies Java qui changent la vie
Librairies Java qui changent la vieLibrairies Java qui changent la vie
Librairies Java qui changent la vie
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
Chapitre 2: String en Java
Chapitre 2:  String en JavaChapitre 2:  String en Java
Chapitre 2: String en Java
 
Javascript Json artchitecture
Javascript  Json artchitecture Javascript  Json artchitecture
Javascript Json artchitecture
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
 
Eric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharpEric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharp
 
Développement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresDéveloppement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulières
 
Introduction java
Introduction javaIntroduction java
Introduction java
 
Introduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El HassaniIntroduction à Python - Achraf Kacimi El Hassani
Introduction à Python - Achraf Kacimi El Hassani
 

Plus de Jean-Michel Doudoux

Javaday Paris 2022 - Java en 2022 : profiter de Java 17
Javaday Paris 2022 - Java en 2022 : profiter de Java 17Javaday Paris 2022 - Java en 2022 : profiter de Java 17
Javaday Paris 2022 - Java en 2022 : profiter de Java 17Jean-Michel Doudoux
 
Voxxeddays Lux 2022 - Profiling et monitoring avec le JDK
Voxxeddays Lux 2022 - Profiling et monitoring avec le JDKVoxxeddays Lux 2022 - Profiling et monitoring avec le JDK
Voxxeddays Lux 2022 - Profiling et monitoring avec le JDKJean-Michel Doudoux
 
devoxx 2022 - 10 ans de Devoxx FR et de Java.pdf
devoxx 2022 - 10 ans de Devoxx FR et de Java.pdfdevoxx 2022 - 10 ans de Devoxx FR et de Java.pdf
devoxx 2022 - 10 ans de Devoxx FR et de Java.pdfJean-Michel Doudoux
 
Lyon JUG 2018 - Java le changement c'est maintenant
Lyon JUG 2018 - Java le changement c'est maintenantLyon JUG 2018 - Java le changement c'est maintenant
Lyon JUG 2018 - Java le changement c'est maintenantJean-Michel Doudoux
 
Nantes jug 2018 - Java le changement c'est maintenant
Nantes jug 2018 - Java le changement c'est maintenantNantes jug 2018 - Java le changement c'est maintenant
Nantes jug 2018 - Java le changement c'est maintenantJean-Michel Doudoux
 
Voxxeddays lux 2018 apres java 8, java 9 et 10
Voxxeddays lux 2018 apres java 8, java 9 et 10Voxxeddays lux 2018 apres java 8, java 9 et 10
Voxxeddays lux 2018 apres java 8, java 9 et 10Jean-Michel Doudoux
 
Anniversaire Paris JUG - Deja 10 ans - retour vers le futur avec JMX
Anniversaire Paris JUG -  Deja 10 ans - retour vers le futur avec JMXAnniversaire Paris JUG -  Deja 10 ans - retour vers le futur avec JMX
Anniversaire Paris JUG - Deja 10 ans - retour vers le futur avec JMXJean-Michel Doudoux
 
Devoxx 2018 Après Java 8, Java 9 et 10
Devoxx 2018 Après Java 8, Java 9 et 10Devoxx 2018 Après Java 8, Java 9 et 10
Devoxx 2018 Après Java 8, Java 9 et 10Jean-Michel Doudoux
 
Apres java 8, java 9 et 10 - BreizhCamp 2018
Apres java 8, java 9 et 10 - BreizhCamp 2018Apres java 8, java 9 et 10 - BreizhCamp 2018
Apres java 8, java 9 et 10 - BreizhCamp 2018Jean-Michel Doudoux
 
Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Jean-Michel Doudoux
 
Voxxdays luxembourg 2016 retours java 8
Voxxdays luxembourg 2016 retours java 8Voxxdays luxembourg 2016 retours java 8
Voxxdays luxembourg 2016 retours java 8Jean-Michel Doudoux
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Jean-Michel Doudoux
 
"Input/Ouput, 16 ans après" à Devoxx France 2012
"Input/Ouput, 16 ans après" à Devoxx France 2012"Input/Ouput, 16 ans après" à Devoxx France 2012
"Input/Ouput, 16 ans après" à Devoxx France 2012Jean-Michel Doudoux
 

Plus de Jean-Michel Doudoux (13)

Javaday Paris 2022 - Java en 2022 : profiter de Java 17
Javaday Paris 2022 - Java en 2022 : profiter de Java 17Javaday Paris 2022 - Java en 2022 : profiter de Java 17
Javaday Paris 2022 - Java en 2022 : profiter de Java 17
 
Voxxeddays Lux 2022 - Profiling et monitoring avec le JDK
Voxxeddays Lux 2022 - Profiling et monitoring avec le JDKVoxxeddays Lux 2022 - Profiling et monitoring avec le JDK
Voxxeddays Lux 2022 - Profiling et monitoring avec le JDK
 
devoxx 2022 - 10 ans de Devoxx FR et de Java.pdf
devoxx 2022 - 10 ans de Devoxx FR et de Java.pdfdevoxx 2022 - 10 ans de Devoxx FR et de Java.pdf
devoxx 2022 - 10 ans de Devoxx FR et de Java.pdf
 
Lyon JUG 2018 - Java le changement c'est maintenant
Lyon JUG 2018 - Java le changement c'est maintenantLyon JUG 2018 - Java le changement c'est maintenant
Lyon JUG 2018 - Java le changement c'est maintenant
 
Nantes jug 2018 - Java le changement c'est maintenant
Nantes jug 2018 - Java le changement c'est maintenantNantes jug 2018 - Java le changement c'est maintenant
Nantes jug 2018 - Java le changement c'est maintenant
 
Voxxeddays lux 2018 apres java 8, java 9 et 10
Voxxeddays lux 2018 apres java 8, java 9 et 10Voxxeddays lux 2018 apres java 8, java 9 et 10
Voxxeddays lux 2018 apres java 8, java 9 et 10
 
Anniversaire Paris JUG - Deja 10 ans - retour vers le futur avec JMX
Anniversaire Paris JUG -  Deja 10 ans - retour vers le futur avec JMXAnniversaire Paris JUG -  Deja 10 ans - retour vers le futur avec JMX
Anniversaire Paris JUG - Deja 10 ans - retour vers le futur avec JMX
 
Devoxx 2018 Après Java 8, Java 9 et 10
Devoxx 2018 Après Java 8, Java 9 et 10Devoxx 2018 Après Java 8, Java 9 et 10
Devoxx 2018 Après Java 8, Java 9 et 10
 
Apres java 8, java 9 et 10 - BreizhCamp 2018
Apres java 8, java 9 et 10 - BreizhCamp 2018Apres java 8, java 9 et 10 - BreizhCamp 2018
Apres java 8, java 9 et 10 - BreizhCamp 2018
 
Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017
 
Voxxdays luxembourg 2016 retours java 8
Voxxdays luxembourg 2016 retours java 8Voxxdays luxembourg 2016 retours java 8
Voxxdays luxembourg 2016 retours java 8
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016
 
"Input/Ouput, 16 ans après" à Devoxx France 2012
"Input/Ouput, 16 ans après" à Devoxx France 2012"Input/Ouput, 16 ans après" à Devoxx France 2012
"Input/Ouput, 16 ans après" à Devoxx France 2012
 

Les nouveautés de Java 19, 20 et 21 - RivieraDev 2023

  • 1. 1 les nouveautés de Java 19, 20 et 21 @jmdoudoux JMdoudouX 11 juillet 2023
  • 2. Sciam Java 19, 20 et 21 2 Java poursuit son évolution En respectant le rythme de release tous les 6 mois Java 19 Java 20 Java 21 Publication 20 / 09 / 2022 21 / 03 / 2023 19 / 09 / 2023 Spécification JSR 394 JSR 395 JSR 396 Implémentation de référence OpenJDK 19 OpenJDK 20 OpenJDK 21 Durée des patchs 6 mois 6 mois > 2 ans Nb JEPs 7 7 15 JDK 21 est une version LTS Depuis la réduction de 3 à 2 ans entre 2 LTS après Java 17
  • 3. Sciam Les JEPs de Java 19, 20 et 21 Java 19 et 20 3 JEP 440 : Record Patterns JEP 442 : Foreign Function & Memory API (Third Preview) JEP 444 : Virtual Threads JEP 441 : Pattern Matching for switch JEP 448 : Vector API (Sixth Incubator) JEP 453 : Structured Concurrency (Preview) JEP 446 : Scoped Values (Preview) JEP 430 : String Templates (Preview) JEP 431 : Sequenced Collections JEP 439 : Generational ZGC JEP 443 : Unnamed Patterns and Variables (Preview) JEP 445 : Unnamed Classes and Instance Main Methods (Preview) JEP 449 : Deprecate the Windows 32-bit x86 Port for Removal JEP 451 : Prepare to Disallow the Dynamic Loading of Agents JEP 452 : Key Encapsulation Mechanism API Java 21 JEP 405 et 432 : Record Patterns (Preview) JEP 424 et 434 : Foreign Function & Memory API (Preview) JEP 425 et 436 : Virtual Threads (Preview) JEP 427 et 433 : Pattern Matching for switch (Preview) JEP 426 et 438 : Vector API (Incubator) JEP 428 et 437 : Structured Concurrency (Incubator) JEP 429 : Scoped Values (Incubator) JEP 422 : Linux/RISC-V Port
  • 4. Sciam 4 Jean-Michel Doudoux https://www.jmdoudoux.fr @jmdoudoux Co-fondateur du Auteur de 2 didacticiels Diffusés sous licence GNU FDL • Développons en Java (4000 pages) • Développons en Java avec Eclipse Senior Tech Lead chez
  • 5. Sciam Roadmap Les fonctionnalités du projet Amber 5 Les évolutions du projet Loom dans la JVM Hotspot dans les API Java Core Les fonctionnalités du projet Panama
  • 6. Sciam Les fonctionnalités du projet Amber Record Patterns Pattern Matching for switch String Templates (Preview) Unnamed Patterns and Variables (Preview) Unnamed Classes and Instance Main Methods (Preview)
  • 7. Sciam Record Patterns En preview en Java 19 (JEP 420) et 20 (JEP 432) 7 Standard en Java 21 Type pattern utilisable avec le pattern matching sur les records record Employe(String nom, String prenom) {} Object o = new Employe("Nom1", "Prenom1"); if (o instanceof Employe emp) { System.out.println("Employe : "+emp.nom()+" "+emp.prenom()); } Ajouter un nouveau pattern utilisable dans le pattern matching Le record pattern pour déconstruire les valeurs d’un record if (o instanceof Employe(String nom, String prenom)) { System.out.println("Employe : "+nom+" "+prenom); }
  • 8. Sciam switch (o) { case Employe emp -> System.out.println(emp); case Grade(String code,String designation) -> System.out.println("Grade " + designation + "(" + code + ")"); default -> System.out.println("Type non supporté"); } Record Patterns Utilisable avec une instruction instanceof ou switch Type pattern et record pattern peuvent être combinés Dans un même switch Java 20 : utilisable dans une boucle for améliorée List<Employe> employes = List.of(new Employe("Nom1", "Prenom1")); for(Employe(var nom, var prenom) : employes) { System.out.println(nom + " " + prenom); } 8 Java 21 : retiré
  • 9. Sciam Record Patterns Le nom des variables peut être différents de celui des composants Seuls l’ordre et le type des composants doivent être respectés if (o instanceof Employe(String n, String p)) { System.out.println("Employe : " + n + " " + p); } if (o instanceof Employe(var nom, var prenom)) { System.out.println("Employe : "+nom+" "+prenom); } Utilisation possible de l’inférence du type dans le pattern 9 record Mono<T>(T val) implements Container<T> {} Mono<Mono<String>> monoDeMono = new Mono<>(new Mono<>("valeur")); Java 20 : support de l'inférence des types d’arguments génériques if (monoDeMono instanceof Mono(Mono(var s))) { System.out.println("mono contient " + s); }
  • 10. Sciam record Grade(String code, String designation) {} record Employe(String nom, String prenom, Grade grade) {} Object o = new Employe("Nom1", "Prenom1", new Grade("DEV", "Développeur")); if (o instanceof Employe(var nom, var prenom, Grade(var code, var designation))) { System.out.println("Employe : " + nom + " " + prenom + ", "+ designation); } Record Patterns Les record patterns peuvent être imbriqués La valeur null ne correspond à aucun record pattern 10
  • 11. Sciam Pattern Matching for switch Historiquement 4 preview en Java 17 (JEP 406), 18 (JEP 420), 19 (JEP 427) et 20 (JEP 433) But : utiliser le pattern matching dans une instruction switch En maintenant la compatibilité syntaxique Avec un support de la valeur null contrairement à la levée historique d’une NPE 11 static String getDesignation(Object obj) { String designation = switch (obj) { case Terrain t -> "Terrain"; case null -> "Instance null"; default -> "Pas un terrain"; }; return designation; } Standard en Java 21 Plusieurs patterns utilisables Type pattern Teste la correspondance sur un type
  • 12. Sciam Pattern Matching for switch Record Pattern Déconstruit un record Utilise le nouveau mot clé contextuel when 12 static String getDesignation(Object obj) { String designation = switch (obj) { case Terrain t when (t.getSurface() > 1000) -> "Grand terrain"; case Terrain t -> "Petit terrain"; case null -> "Instance null"; default -> "Pas un terrain"; }; return designation; } Utilisation possible d’un Guarded pattern case label Combine un pattern et une expression booléenne dans un case Parenthesized pattern retiré en Java 21
  • 13. Sciam Pattern Matching for switch Possibilité de mixer constantes et patterns 13 L’exhaustivité des cas d’un switch doit être satisfaite Sinon erreur de compilation : implique fréquemment l’utilisation d’un default Au runtime une exception de type java.lang.MatchException est levée Exemple : sur un type scellé ou une énumération par exemple String getEnv(String env) { return switch (env) { case "Prod" -> "Production"; case String s -> "Hors production"; }; } static String formater(Number nombre) { return switch (nombre) { // erreur : the switch expression does not cover all possible input values case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); }; }
  • 14. Sciam Pattern Matching for switch Le compilateur vérifie la dominance des patterns Les patterns les plus restrictifs doivent être avant les moins restrictifs 14 static String formater(Object o) { return switch (o) { case Number n -> String.format("number %f", n); case Integer i -> String.format("int %d", i); // erreur this case label is dominated by a preceding case label case Long l -> String.format("long %d", l); default -> o.toString(); }; } Idem avec les guarded patterns case label String taille = switch (chaine) { case String s -> "Moyenne"; case String s when s.length() < 10 -> "Petite"; // erreur this case label is dominated by a preceding case label case String s when s.length() > 100 -> "Grande"; };
  • 15. Sciam Pattern Matching for switch Sémantique d'exécution d’un switch avec le pattern matching Lorsque la valeur est null et que le cas null n’est pas explicitement géré : Elle est étroitement alignée sur la sémantique historique des switchs 15 public static void main(String[] args) { String chaine = null; switch (chaine) { case String s -> { System.out.println("traitement chaine"); System.out.println("taille : " + s.length()); } } } Exception in thread "main" java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:233) at TestSwitchPattern.main(TestSwitchPattern.java:5)
  • 16. Sciam Java 21 autorise les constantes d'énumération qualifiées Dans les cases des switchs afin d’éviter d’avoir à utiliser un guarded pattern case label 16 public sealed interface MonInterface permits MonEnum, MaClasse {} public enum MonEnum implements MonInterface { PAIRE, IMPAIRE } public final class MaClasse implements MonInterface {} // … static void traiter(MonInterface c) { switch (c) { // case MonEnum e when e == MonEnum.PAIRE -> { System.out.println("Paire"); } case MonEnum.PAIRE -> { System.out.println("Paire"); } case MonEnum.IMPAIRE -> { System.out.println("Impaire"); } case MonEnum e -> { System.out.println("MonEnum"); } case MaClasse mc -> { System.out.println("MaClasse"); } } } Pattern Matching for switch
  • 17. Sciam String Templates (Preview) Courant de devoir créer des chaînes de caractères composées À partir d'une combinaison de textes littéraux Et de valeurs ou d'expressions 17 Historiquement plusieurs fonctionnalités, toutes avec inconvénients String s = x + " + " + y + " = " + (x + y); MessageFormat mf = new MessageFormat("{0} + {1} = {2}"); String s = mf.format(x, y, x + y); String s = String.format("%2$d + %1$d = %3$d", x, y, x + y); String t = "%2$d + %1$d = %3$d".formatted(x, y, x + y); String s = new StringBuilder() .append(x) .append(" + ") .append(y) .append(" = ") .append(x + y) .toString(); De nombreux langages proposent l'interpolation de chaînes Comme alternative à la concaténation de chaînes
  • 18. Sciam String Templates (Preview) La plupart des langages supportent l’interpolation de chaînes Mais le résultat peut parfois engendrer des soucis indirects Exemple : SQL ou JSON injection 18 En combinant : - Un texte littéral avec des expressions intégrées - Et un processeur de templates Pour produire des chaînes de caractères construites dynamiquement Avec la clarté de l’interpolation et un résultat plus sûr Le but : enrichir le langage Java avec des string templates Qui complètent les chaînes littérales et les blocs de texte Possibilité de créer une instance de type quelconque Avec un processeur de templates personnalisés
  • 19. Sciam String Templates (Preview) Nouveau type d'expression dans le langage : les templates expressions Pour effectuer une interpolation de chaîne pour créer une chaîne ou un objet 19 Syntaxiquement, ressemble à une chaîne littérale avec un préfixe : String prenom = "Jean-Michel"; String message = STR."Bonjour {prenom}"; Une template expression est composée de trois éléments : 1) Un processeur de templates (STR) 2) Un caractère point (U+002E), celui utilisé dans les autres expressions 3) Un template ("Bonjour {prenom}") qui contient une expression intégrée ({prenom}) Le template peut utiliser plusieurs lignes de code source En utilisant une syntaxe similaire à celle des blocs de texte
  • 20. Sciam String Templates (Preview) 3 processeurs de templates dans le JDK 20 STR : effectue une interpolation pour créer une chaîne int x = 10, y = 20; String s = STR."{x} + {y} = {x + y}"; FMT : effectue une interpolation pour créer une chaîne Il interprète les spécificateurs de format à gauche des expressions intégrées Les spécificateurs de format sont ceux définis dans java.util.Formatter RAW : produit un objet de type StringTemplate String prenom = "Jean-Michel"; StringTemplate st = RAW."Bonjour {prenom}"; String message = STR.process(st);
  • 21. Sciam String Templates (Preview) Possibilité de définir des processeurs de templates personnalisés Pour générer des chaînes ou des objets qui peuvent être validés 21 Une instance de l'interface fonctionnelle StringTemplate.Processor Implémenter l’unique méthode process() Utilisation de la fabrique StringTemplate.Processor::of Pour obtenir une instance var JSON = StringTemplate.Processor.of((StringTemplate st) -> new JSONObject(st.interpolate())); String nom = "Durant"; String prenom = "Pierre"; JSONObject doc = JSON.""" { "nom": "{nom}", "prenom": "{prenom}" }""";
  • 22. Sciam Unnamed Patterns and Variables (Preview) Enrichit le langage d’une syntaxe Pour les patterns inutilisés dans les records pattern imbriqués Et les variables inutilisées qui doivent être déclarées 22 Unnamed pattern : un pattern inconditionnel qui ne correspond à rien Utilisable dans un pattern imbriqué à la place d'un type ou record pattern record Grade(String code, String designation) {} record Employe(String nom, String prenom, Grade grade) {} Object o = new Employe("Nom1", "Prenom1", new Grade("DEV", "Développeur")); if (o instanceof Employe(var nom, var prenom, _)) { System.out.println("Employe : " + nom + " " + prenom); } Utilisant le 51eme mot clé réservé de Java : _
  • 23. Sciam Unnamed Patterns and Variables (Preview) Unnamed pattern variable : Utilisable avec tous types de patterns 23 Unnamed variable : peut être initialisée mais non utilisée dans Une variable locale dans un bloc Une ressource dans un try-with-resources L'en-tête d'une boucle for et for améliorée Une exception d'un bloc catch Un paramètre formel d'une expression Lambda try (var _ = ScopedContext.acquire()) { var _ = service.traiter((_, _) -> System.out.printn("traiter")); } catch (Throwable _) { } if (o instanceof Employe(var nom, var _, _)) { System.out.println("Employe : " + nom); } Utilisable plusieurs fois dans la même portée
  • 24. Sciam Unnamed Patterns and Variables (Preview) Utile dans des switchs avec des patterns sur des types scellés 24 void traiterFormeRonde(Forme forme) { switch(forme) { case Cercle c -> afficher(c); case Carre c -> {} case Rectangle r -> {} } } switch(forme) { case Cercle c -> afficher(c); default -> {} } switch(forme) { case Cercle c -> afficher(c); case Carre _, Rectangle _ -> {} } Impossible d’avoir plusieurs patterns nommés dans un case Risque de bug en cas d’ajout d’un type : sealed interface Forme permits Cercle, Carre, Rectangle {} Utilisation possible de default préférable d’utiliser des unnamed variables
  • 25. Sciam Unnamed Classes and Instance Main Methods (Preview) 25 Plutôt compliqué public class HelloWorld { public static void main(String[] args) { System.out.println("Hello world"); } } Les buts : Faire évoluer le langage pour simplifier les programmes simples Et faciliter l’apprentissage des débutants avec le langage Java Méthode d’instance main() class HelloWorld { void main() { System.out.println("Hello world"); } } void main() { System.out.println("Hello world"); } Classe sans nom (unnamed class) Deux évolutions dans une classe unique
  • 26. Sciam Les fonctionnalités du projet Loom Virtual Threads Structured Concurrency (Preview) Scoped Values (Preview)
  • 27. Sciam Virtual Threads Chaque thread Java est directement mappé à un thread de l’OS Depuis Java 1.0 Ce modèle n’est pas optimal Car un thread de la plateforme est coûteux en ressources Notamment à cause de la taille fixe (par défaut) de sa pile 27 Cela limite le nombre de threads qui peuvent être utilisés Décharge la JVM de se préoccuper de tâches réalisées par l’OS Ordonnancement et changement de contexte des threads Or on utilise de plus en plus de threads Qui généralement passent beaucoup de temps à attendre la fin d’une opération bloquante
  • 28. Sciam Virtual Threads Introduction d’un nouveau type de threads : des threads virtuels Plusieurs objectifs : 28 Ce sont des threads « légers » gérés dans la JVM Non lié à un thread de la plate-forme dédié Qu’il utilise uniquement lors de l’utilisation de la CPU par ses traitements • Assurer une adoption par le code existant Qui utilise l'API java.lang.Thread avec un impact minimum • Conserver le style « un thread par requête » Avec une meilleure utilisation des ressources requises • Permettre le débogage, le profilage et le dépannage Avec les outils existants du JDK En preview Java 19 (JEP 425) et 20 (JEP 436) En standard Java 21 (JEP 444)
  • 29. Sciam Virtual Threads Exécutent du code qui ne bloque pas les threads de l’OS Contrairement aux verrous ou aux opérations bloquantes (I/O par exemple) Si le thread virtuel exécute une action bloquante dans les API du JDK La JVM enregistrement la stack dans le heap et exécute l’action en non bloquante 29 Le thread porteur peut alors exécuter un autre thread virtuel Mapping M:N entre threads virtuels et threads de l’OS Grâce à un ForkJoinPool dédié qui fournit les threads porteurs (carrier threads) Une fois l’action non bloquante terminée L’exécution des traitements du thread virtuel est reprise sur un thread porteur Potentiellement différent Ce mécanisme est géré en interne par les API du JDK En utilisant des objets de type Continuation et ContinuationScope Et est transparent pour le développeur
  • 30. Sciam Virtual Threads La classe finale package-private java.lang.VirtualThread Hérite de java.lang.Thread Pas de constructeur public L’interface scellée Thread.Buidler propose deux interfaces filles Thread.Builder.OfVirtual et Thread.Builder.OfPlatform Dont on obtient une instance avec Thread::ofVirtual et Thread::ofPlatform 30 Le plus simple est d’utiliser Thread::startVirtualThread Pour démarrer un nouveau thread virtuel qui exécute un Runnable Thread t = Thread.startVirtualThread(() -> { System.out.println("Thread : " + Thread.currentThread()); }); var threadVirtuel = Thread.ofVirtual().name("app-thread-virtuel-", 0).start(() -> { System.out.println(Thread.currentThread()); }); threadVirtuel.join();
  • 31. Sciam Virtual Threads Plusieurs restrictions sur les threads virtuels : 31 • Ils sont obligatoirement des threads démons • stop(), resume(), suspend() lèvent une UnsupportedOperationException • La priorité est obligatoirement Thread.NORM_PRIORITY • Ils ne peuvent pas être associés à un ThreadGroup • getThreadGroup() renvoie un groupe "VirtualThreads" fictif qui est vide • getAllStackTraces() renvoie une Map qui contient uniquement que les threads de l’OS plutôt que de tous les threads Ne pas mettre les threads virtuels dans un pool Aucune utilité vue leur faible coût de création
  • 32. Sciam Virtual Threads Peuvent améliorer le débit des applications Lorsque le nombre de tâches simultanées est important Et que les tâches ne requièrent pas de manière intensive la CPU 32 Deux scénarios bloquants peuvent limiter l’intérêt des threads virtuels Car ils laissent le thread virtuel associé à son thread porteur • L’exécution d’un bloc de code synchronized Il est préférable d’utiliser si possible un ReentrantLock • Lors de l’exécution d’une méthode native Option de la JVM pour identifier ces cas Un événement JFR : jdk.VirtualThreadPinned -Djdk.tracePinnedThreads=full ou short
  • 33. Sciam Structured Concurrency (preview) Propose un nouveau modèle de programmation Grâce au traitement de plusieurs tâches Exécutées dans différents threads virtuels comme une seule unité de travail 33 Fork/Join et concurrence structurée sont complémentaires Le but : simplifier la programmation multithread En rationalisant la gestion des erreurs et l'annulation, En améliorant la fiabilité et en renforçant l'observabilité Fork/Join Conçu pour traiter des tâches à forte intensité de calcul sur une courte durée Utilise des threads de l’OS Complexe à mettre œuvre Concurrence structurée Conçue pour traiter des tâches à forte intensité d'E/S Utilise des threads virtuels Facile à mettre en oeuvre
  • 34. Sciam Structured Concurrency (preview) API en incubation en Java 20 Classe principale : java.util.concurrent.StructuredTaskScope 34 Le modèle permet une écriture du code dans un style synchrone Avec une exécution en asynchrone Le code est ainsi facile à écrire, à lire et à tester API en preview en Java 21 Dans le package java.util.concurrent
  • 35. Sciam Structured Concurrency (preview) La mise en œuvre en plusieurs étapes 35 • Créer une instance dans un try-with-resource Facture getFacture(String codeClient, long idCommande) throws ExecutionException, InterruptedException, TimeoutException { Facture resultat = null; try (var scope = new StructuredTaskScope()) { Subtask<Client> clientFuture = scope.fork(() -> this.getClient(codeClient)); Subtask <Commande> commandeFuture = scope.fork(() -> this.getCommande(idCommande)); scope.joinUntil(Instant.now().plusSeconds(15)); resultat = this.genererFacture(clientFuture.get(), commandeFuture.get()); } return resultat; } • Invoquer la méthode fork() pour chaque sous-tâche à exécuter • Attendre la fin de l’exécution des sous-tâches o Soit sans timeout en utilisant la méthode join() o Soit avec timeout en utilisant la méthode joinUntil() • Exploiter les résultats obtenus dans des instances de type Subtask (Future en Java 20)
  • 36. Sciam Structured Concurrency (preview) La classe StructuredTaskScope.ShutdownOnFailure Propose un modèle invoke all 36 Facture getFacture(String codeClient, long idCommande) throws ExecutionException, InterruptedException, TimeoutException { Facture resultat = null; try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Subtask <Client> clientFuture = scope.fork(() -> this.getClient(codeClient)); Subtask<Commande> commandeFuture = scope.fork(() -> this.getCommande(idCommande)); scope.joinUntil(Instant.now().plusSeconds(15)); scope.throwIfFailed(); resultat = this.genererFacture(clientFuture.get(), commandeFuture.get()); } return resultat; } Qui exécute toutes les sous-tâches Et termine toutes les sous-tâches en cours si une sous-tâche lève une exception
  • 37. Sciam Structured Concurrency (preview) La classe StructuredTaskScope.ShutdownOnSuccess Propose un modèle invoke any 37 Temperature getTemperature(String ville) throws InterruptedException, ExecutionException { Temperature resultat = null; try (var scope = new StructuredTaskScope.ShutdownOnSuccess<Temperature>()) { serviceMeteos.forEach(f -> { scope.fork(() -> f.getTemperature(ville)); } ); scope.join(); resultat = scope.result(); } return resultat; } Qui renvoie le résultat de la première sous-tâche terminée Et termine les autres sous-tâches restantes
  • 38. Sciam Structured Concurrency (preview) Possibilité de créer son propre scope En héritant de la classe StructuredTaskScope Et en y implémentant ses propres règles métiers 38 class ComposantLePlusLegerScope extends StructuredTaskScope<Composant> { private final Collection<Composant> composants = new ConcurrentLinkedQueue<>(); private final Collection<Throwable> exceptions = new ConcurrentLinkedQueue<>(); @Override protected void handleComplete(Subtask<? extends Composant> subtask) { switch (subtask.state()) { case SUCCESS -> this.composants.add(subtask.get()); case FAILED -> this.exceptions.add(subtask.exception()); case UNAVAILABLE -> {} } }
  • 39. Sciam Structured Concurrency (preview) 39 public Exception exceptions() { RuntimeException exception = new RuntimeException("Impossible d'obtenir le composant le plus leger"); exceptions.forEach(exception::addSuppressed); return exception; } public Composant getComposant() throws Exception { return composants.stream().min(Comparator.comparing(Composant::poids)) .orElseThrow(this::exceptions); } }
  • 40. Sciam Scoped Values (Preview) Pour partager des objets dans le code exécuté par un thread Historiquement depuis Java 1.2, on utilise une variable de type ThreadLocal L’API ScopedValue tente de remédier à ces inconvénients 40 Mais cela présente plusieurs risques : Mutable, fuite de mémoire, consommation de ressources public final static ScopedValue<String> VALEUR = ScopedValue.newInstance(); Création d’une instance généralement statique et publique Stocker et de partager des données immuables Pour une durée de vie limitée à des traitements du thread qui les a écrits En incubation dans Java 20 (JEP 429) En preview dans Java 21 (JEP 446)
  • 41. Sciam Scoped Values (Preview) where() pour définir une valeur, chainable pour plusieurs valeurs get() pour obtenir la valeur ou lève une NoSuchElementException 41 Pour exécuter une tâche dans le thread courant System.out.println((VALEUR.isBound() ? VALEUR.get() : "non definie")); isBound() pour savoir si une valeur est associée au thread run() : sous la forme d’une implémentation de Runnable ScopedValue.where(VALEUR, "test").run(() -> { afficherValeur(); }); Ou call() : sous la forme d’une implémentation de Callable String valeur = ScopedValue.where(VALEUR, "test") .<String>call(monService::traiter);
  • 42. Sciam Scoped Values (Preview) Réassociation d’une valeur pour un traitement sous-jacent Partage avec les threads virtuels d’une StucturedTaskScope 42 ScopedValue.where(VALEUR, "valeur", () -> { try (var scope = new StructuredTaskScope<String>()) { afficherValeur(); scope.fork(monServiceA::traiter); scope.fork(monServiceB::traiter); scope.joinUntil(Instant.now().plusSeconds(10)); } catch (InterruptedException | TimeoutException e) { e.printStackTrace(); } }); ScopedValue.where(VALEUR, "valeur").run(() -> { afficherValeur(); // valeur ScopedValue.where(VALEUR, "autre-valeur").run(monService::traiter); // autre-valeur afficherValeur(); // valeur });
  • 43. Sciam Les évolutions dans les API de Java Core Sequenced Collections
  • 44. Sciam Sequenced collections L’API Collections propose des collections ordonnées Mais n’est pas homogène dans les fonctionnalités proposées 44 Les opérations liées à l'ordre de parcours sont soit incohérentes soit absentes Premier élément Dernier élément List list.get(0) list.get(list.size() - 1) Deque deque.getFirst() deque.getLast() SortedSet sortedSet.first() sortedSet.last() LinkedHashSet linkedHashSet.iterator().next() Des implémentations permettent d'obtenir le premier ou le dernier élément Chacune avec leurs méthodes, dont certaines pas évidentes ou inexistantes Idem pour le parcours dans l’ordre inverse
  • 45. Sciam Sequenced collections Introduire 3 nouvelles interfaces Pour représenter des collections avec un ordre de parcours défini 45 Elles possèdent : Des éléments parcourables du premier au dernier élément dans un certain ordre Fournissent des API uniformes pour accéder au 1er et dernier élément Et pour parcourir ses éléments dans l'ordre inverse SequencedSet SequencedCollection SequencedMap
  • 47. Sciam Les évolutions dans la JVM HotSpot Linux/RISC-V Port Generational ZGC Deprecate the Windows 32-bit x86 Port for Removal Prepare to Disallow the Dynamic Loading of Agents
  • 48. Sciam Linux/RISC-V Port RISC-V est une architecture de jeu d'instructions (ISA) RISC libre et gratuite Conçu à l'origine à l'Université Berkeley de Californie Maintenant développé collaborativement sous le parrainage de RISC-V International De nombreux acteurs envisagent son utilisant notamment : Apple, la NASA, de nombreux industriels asiatiques notamment chinois et indiens 48 Anticipe cela avec le portage d’OpenJDK sur Linux/RISC-V Qui est intégré au repository principal dans Java 19 Peu d’appareil grand public utilisant RISC-V actuellement Mais cela risque de changer dans un futur proche
  • 49. Sciam Generational ZGC Rendre le ramasse-miettes ZGC générationnel 49 Tout en maintenant les caractéristiques actuelles Activation avec les options : -XX:+UseZGC -XX:+ZGenerational Les tailles de tas allant de quelques centaines de Mo à 16 To Les temps de pause ne doivent pas dépasser 1 milliseconde ZGC générationnel devrait être une meilleure solution Pour la plupart des cas d'utilisation que le ZGC non générationnel
  • 50. Sciam Les fonctionnalités du projet Panama Foreign Function & Memory API (Third Preview) Vector API (Sixth Incubator)
  • 51. Sciam Foreign Function & Memory API (Third Preview) API de bas niveau pour de manière simple, sûre et efficace : • Accéder à des données en mémoire hors du tas (off heap memory) • Invoquer des fonctions natives Proposée en preview en Java 19 (JEP 424), 20 (JEP 434) et 21 (JEP 442) Elle est maintenant dans le module java.base 51 Historiquement, fusion de 2 JEPs introduites en incubation : Foreign-Memory Access API en Java 14 (JEP 370, 383, et 393) Et Foreign Linker API en Java 16 (JEP 389) Proposée en incubation en Java 17 (JEP 412) et Java 18 (JEP 419) Attention : cette API évolue beaucoup Dans chacune des versions de Java où elle est proposée
  • 52. Sciam L’API de bas niveau 2) Pour invoquer du code natif Une future alternative à l’API JNI présente depuis Java 1.1 52 1) Pour accéder à des données En mémoire hors du tas (off heap memory) De manière sûre et performante Alternative à certaines fonctionnalités De java.nio.ByteBuffer (pas performante mais sûre) Et sun.misc.Unsafe (non standard) Foreign Function & Memory API (Third Preview)
  • 53. Sciam public class DialogFFM { public static void main(String[] args) { try { System.loadLibrary("user32"); Optional<MemorySegment> msgBoxFunction = SymbolLookup.loaderLookup().find("MessageBoxA"); FunctionDescriptor msgBoxFunctionDesc = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS, ADDRESS, JAVA_INT); Linker linker = Linker.nativeLinker(); MethodHandle methodHandle = linker.downcallHandle(msgBoxFunction.get(), msgBoxFunctionDesc); try (Arena offHeap = Arena.ofConfined()) { MemorySegment cStringMessage = offHeap.allocateUtf8String("Voulez-vous utiliser Java 21 ?"); MemorySegment cStringTitre = offHeap.allocateUtf8String("Confirmation"); int bouton = (int) methodHandle.invoke(NULL, cStringMessage, cStringTitre, 36); } } catch (Throwable t) { t.printStackTrace(); } } } 53 Foreign Function & Memory API (Third Preview) Exemple Java 21 sous Windows
  • 54. Sciam Vector API (Sixth Incubator) Exprimer des calculs vectoriels Qui, au moment de l'exécution, sont systématiquement compilés Avec les meilleures instructions vectorielles possibles sur l’architectures CPU Les SIMD sur les CPU supportées : x64 (SSE et AVX) et AArch64 (Neon) Dans le module jdk.incubator.vector 54 Single Instruction, Multiple Data Traiter en parallèle un tableau de données, sans threads Pour appliquer une même opération sur plusieurs valeurs traitées En un seul cycle de traitement CPU En incubation en Java 16 (JEP 338), 17 (JEP 414), 18 (JEP 417), 19 (JEP 426), 20 (JEP 438) et 21 (JEP 448)
  • 55. Sciam static float[] calculerScalaire(float[] a, float[] b) { float[] c = new float[a.length]; for (int i = 0 ; i < a.length ; i++) { c[i] = a[i] * a[i] - b[i] * b[i]; } return c; } 55 API plutôt de bas niveau, verbeuse, dépendant partiellement du CPU Mais qui peut offrir de meilleures performances que le code scalaire équivalent Exemple Java 21 static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED; static float[] calculerVectoriel(float[] a, float[] b) { float[] c = new float[a.length]; int i = 0; for (; i < SPECIES.loopBound(a.length) ; i += SPECIES.length()) { var va = FloatVector.fromArray(SPECIES, a, i); var vb = FloatVector.fromArray(SPECIES, b, i); var vr = va.mul(va).sub(vb.mul(vb)); vr.intoArray(c, i); } for (; i < a.length; i++) { c[i] = a[i] * a[i] - b[i] * b[i]; } return c; } Vector API (Sixth Incubator)
  • 57. Sciam Conclusion Java poursuit son évolution en respectant son modèle de releases La syntaxe, particulièrement le pattern matching 57 Java 21 proposent des fonctionnalités concernant Cela permettra à Java de rester pertinent aujourd’hui et demain La programmation parallèle et concurrente Une meilleure utilisation du matériel moderne N’hésitez pas à télécharger l’Early Access : https://jdk.java.net/21/ Java 21, le 19 septembre 2023 Pour anticiper la release de la prochaine version LTS du JDK
  • 59. Sciam