API de Flux Parallèles
Vous connaissez probablement déjà le Stream API, ses méthodes et son fonctionnement (Sinon, étudiez ce sujet puis revenez à ce chapitre).
Un flux de données classique n'est pas parallèle ; aussi pratique et élégant soit-il dans le code, utiliser le Stream API sans la méthode parallelStream() avec un grand volume de données peut fortement impacter les performances.
Il existe également une méthode parallel() qui peut être utilisée après la conversion en stream.
List<Integer> result = list.stream().parallel()
.map(num -> ++num)
.toList();
La différence est que parallelStream() crée un flux parallèle directement à partir de la collection, tandis que parallel() convertit un flux sériel existant en un flux parallèle.
Et surtout, en tant que programmeurs, il n'est pas nécessaire de faire quoi que ce soit d'autre que de remplacer la méthode stream() par parallelStream(). Le Stream API s'occupe de tout et optimise notre programme !
Exemple : Traitement d'une liste de nombres
Supposons que nous ayons une liste de nombres et que nous souhaitions trouver la somme des carrés de tous les nombres de la liste.
Main.java
123456789101112131415161718192021222324252627package com.example; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of integers List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Sequential stream to sum the squares of numbers int sumSequential = numbers.stream() // Create a sequential stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the sequential sum System.out.println("Sum of squares (sequential): " + sumSequential); // Parallel stream to sum the squares of numbers int sumParallel = numbers.parallelStream() // Create a parallel stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the parallel sum System.out.println("Sum of squares (parallel): " + sumParallel); } }
Comme vous pouvez le constater, nous avons simplement remplacé stream() par parallelStream() ET C'EST TOUT. Dans cet exemple, cela n'apportera aucun gain, car dans un environnement à un seul thread, un tableau de 10 caractères sera exécuté plus rapidement. En effet, l'implémentation de la Stream API effectue de nombreuses opérations pour répartir la tâche entre les threads.
Stream API décide également lui-même du nombre de threads à utiliser pour cette tâche, afin d’être aussi efficace que possible.
Fonctionnement interne :
1. Création d’un flux parallèle : Lors de l’appel à parallelStream(), Java crée un flux parallèle basé sur la source de données d’origine ;
2. Utilisation de ForkJoinPool (nous l’examinerons plus tard) : Les flux parallèles utilisent un pool de threads commun, ForkJoinPool.commonPool(), qui gère un groupe de threads de travail ;
3. Découpage : Les données dans un thread parallèle sont divisées en parties à l’aide de l’interface Spliterator ;
4. Traitement : Chaque thread de travail dans ForkJoinPool traite sa partie des données ;
5. Fusion : Après le traitement des données, les threads de travail fusionnent les résultats.
Avantages des flux parallèles
Performance accrue parmi les principaux bénéfices des threads parallèles, grâce à la répartition des tâches sur plusieurs threads, ce qui permet un traitement plus rapide sur les processeurs multi-cœurs.
De plus, la simplicité d’utilisation de l’API des threads parallèles facilite son intégration dans le code existant, sans nécessiter une gestion complexe des threads.
Enfin, la scalabilité constitue un avantage majeur, car les threads parallèles s’ajustent automatiquement au nombre de cœurs processeur disponibles, optimisant ainsi l’exécution des tâches de manière efficace.
1. Quelle classe est utilisée par les threads parallèles pour contrôler les threads ?
2. Quelle méthode est utilisée pour créer un flux parallèle ?
3. Que fait l’interface Spliterator dans le contexte des flux parallèles ?
Merci pour vos commentaires !
Demandez à l'IA
Demandez à l'IA
Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion
Can you explain when it's best to use parallel streams versus regular streams?
What are some potential drawbacks or risks of using parallel streams?
Can you provide more examples of using parallel streams in Java?
Awesome!
Completion rate improved to 3.33
API de Flux Parallèles
Glissez pour afficher le menu
Vous connaissez probablement déjà le Stream API, ses méthodes et son fonctionnement (Sinon, étudiez ce sujet puis revenez à ce chapitre).
Un flux de données classique n'est pas parallèle ; aussi pratique et élégant soit-il dans le code, utiliser le Stream API sans la méthode parallelStream() avec un grand volume de données peut fortement impacter les performances.
Il existe également une méthode parallel() qui peut être utilisée après la conversion en stream.
List<Integer> result = list.stream().parallel()
.map(num -> ++num)
.toList();
La différence est que parallelStream() crée un flux parallèle directement à partir de la collection, tandis que parallel() convertit un flux sériel existant en un flux parallèle.
Et surtout, en tant que programmeurs, il n'est pas nécessaire de faire quoi que ce soit d'autre que de remplacer la méthode stream() par parallelStream(). Le Stream API s'occupe de tout et optimise notre programme !
Exemple : Traitement d'une liste de nombres
Supposons que nous ayons une liste de nombres et que nous souhaitions trouver la somme des carrés de tous les nombres de la liste.
Main.java
123456789101112131415161718192021222324252627package com.example; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of integers List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Sequential stream to sum the squares of numbers int sumSequential = numbers.stream() // Create a sequential stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the sequential sum System.out.println("Sum of squares (sequential): " + sumSequential); // Parallel stream to sum the squares of numbers int sumParallel = numbers.parallelStream() // Create a parallel stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the parallel sum System.out.println("Sum of squares (parallel): " + sumParallel); } }
Comme vous pouvez le constater, nous avons simplement remplacé stream() par parallelStream() ET C'EST TOUT. Dans cet exemple, cela n'apportera aucun gain, car dans un environnement à un seul thread, un tableau de 10 caractères sera exécuté plus rapidement. En effet, l'implémentation de la Stream API effectue de nombreuses opérations pour répartir la tâche entre les threads.
Stream API décide également lui-même du nombre de threads à utiliser pour cette tâche, afin d’être aussi efficace que possible.
Fonctionnement interne :
1. Création d’un flux parallèle : Lors de l’appel à parallelStream(), Java crée un flux parallèle basé sur la source de données d’origine ;
2. Utilisation de ForkJoinPool (nous l’examinerons plus tard) : Les flux parallèles utilisent un pool de threads commun, ForkJoinPool.commonPool(), qui gère un groupe de threads de travail ;
3. Découpage : Les données dans un thread parallèle sont divisées en parties à l’aide de l’interface Spliterator ;
4. Traitement : Chaque thread de travail dans ForkJoinPool traite sa partie des données ;
5. Fusion : Après le traitement des données, les threads de travail fusionnent les résultats.
Avantages des flux parallèles
Performance accrue parmi les principaux bénéfices des threads parallèles, grâce à la répartition des tâches sur plusieurs threads, ce qui permet un traitement plus rapide sur les processeurs multi-cœurs.
De plus, la simplicité d’utilisation de l’API des threads parallèles facilite son intégration dans le code existant, sans nécessiter une gestion complexe des threads.
Enfin, la scalabilité constitue un avantage majeur, car les threads parallèles s’ajustent automatiquement au nombre de cœurs processeur disponibles, optimisant ainsi l’exécution des tâches de manière efficace.
1. Quelle classe est utilisée par les threads parallèles pour contrôler les threads ?
2. Quelle méthode est utilisée pour créer un flux parallèle ?
3. Que fait l’interface Spliterator dans le contexte des flux parallèles ?
Merci pour vos commentaires !