API de Flujo Paralelo
Probablemente ya estés familiarizado con la Stream API, sus métodos y cómo funciona (si no es así, estudia este tema y luego regresa a este capítulo).
Un flujo de datos regular no es paralelo, es decir, por muy conveniente y elegante que sea en el código, utilizar la Stream API sin emplear el método parallelStream(), con una gran cantidad de datos, puede afectar significativamente el rendimiento.
También existe un método parallel() que se puede utilizar después de la conversión a stream.
List<Integer> result = list.stream().parallel()
.map(num -> ++num)
.toList();
La diferencia es que parallelStream() crea un flujo paralelo directamente desde la colección, mientras que parallel() convierte un flujo secuencial existente en un flujo paralelo.
Y sobre todo, como programadores, no necesitamos hacer nada más que cambiar el método stream() por parallelStream(). La Stream API realiza todo el trabajo y optimiza nuestro programa.
Ejemplo: Procesamiento de una lista de números
Supongamos que tenemos una lista de números y queremos encontrar la suma de los cuadrados de todos los números en la lista.
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); } }
Como puede ver, simplemente reemplazamos stream() por parallelStream() Y ESO ES TODO. En este ejemplo no habrá ninguna ganancia, porque en un entorno de un solo hilo, un arreglo de 10 caracteres se ejecutará más rápido. Esto se debe a que la implementación de la Stream API realiza muchas acciones para distribuir la tarea entre los hilos.
Stream API también decide por sí mismo cuántos hilos utilizará para esta tarea, de modo que sea lo más eficiente posible.
Cómo funciona internamente:
1. Creación de un stream paralelo: Cuando se llama a parallelStream(), Java crea un stream paralelo basado en la fuente de datos original;
2. Uso de ForkJoinPool (lo exploraremos más adelante): Los streams paralelos utilizan un pool de hilos común, ForkJoinPool.commonPool(), que gestiona un grupo de hilos de trabajo;
3. División: Los datos en un hilo paralelo se dividen en partes utilizando la interfaz Spliterator;
4. Procesamiento: Cada hilo de trabajo en ForkJoinPool procesa su parte de los datos;
5. Fusión: Tras procesar los datos, los hilos de trabajo fusionan los resultados.
Ventajas de los Streams Paralelos
Mayor rendimiento es uno de los beneficios clave de los hilos paralelos, ya que permiten la distribución de tareas entre múltiples hilos, lo que resulta en un procesamiento más rápido en procesadores multinúcleo.
Además, la facilidad de uso de la API de hilos paralelos permite una integración sencilla en el código existente, eliminando la necesidad de una gestión compleja de hilos.
Asimismo, la escalabilidad es una ventaja significativa, ya que los hilos paralelos se ajustan automáticamente al número de núcleos de procesador disponibles, optimizando la ejecución de tareas de manera eficiente.
1. ¿Qué clase es utilizada por los hilos paralelos para controlar los hilos?
2. ¿Qué método se utiliza para crear un flujo paralelo?
3. ¿Qué hace la interfaz Spliterator en el contexto de los flujos paralelos?
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla
Awesome!
Completion rate improved to 3.33
API de Flujo Paralelo
Desliza para mostrar el menú
Probablemente ya estés familiarizado con la Stream API, sus métodos y cómo funciona (si no es así, estudia este tema y luego regresa a este capítulo).
Un flujo de datos regular no es paralelo, es decir, por muy conveniente y elegante que sea en el código, utilizar la Stream API sin emplear el método parallelStream(), con una gran cantidad de datos, puede afectar significativamente el rendimiento.
También existe un método parallel() que se puede utilizar después de la conversión a stream.
List<Integer> result = list.stream().parallel()
.map(num -> ++num)
.toList();
La diferencia es que parallelStream() crea un flujo paralelo directamente desde la colección, mientras que parallel() convierte un flujo secuencial existente en un flujo paralelo.
Y sobre todo, como programadores, no necesitamos hacer nada más que cambiar el método stream() por parallelStream(). La Stream API realiza todo el trabajo y optimiza nuestro programa.
Ejemplo: Procesamiento de una lista de números
Supongamos que tenemos una lista de números y queremos encontrar la suma de los cuadrados de todos los números en la lista.
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); } }
Como puede ver, simplemente reemplazamos stream() por parallelStream() Y ESO ES TODO. En este ejemplo no habrá ninguna ganancia, porque en un entorno de un solo hilo, un arreglo de 10 caracteres se ejecutará más rápido. Esto se debe a que la implementación de la Stream API realiza muchas acciones para distribuir la tarea entre los hilos.
Stream API también decide por sí mismo cuántos hilos utilizará para esta tarea, de modo que sea lo más eficiente posible.
Cómo funciona internamente:
1. Creación de un stream paralelo: Cuando se llama a parallelStream(), Java crea un stream paralelo basado en la fuente de datos original;
2. Uso de ForkJoinPool (lo exploraremos más adelante): Los streams paralelos utilizan un pool de hilos común, ForkJoinPool.commonPool(), que gestiona un grupo de hilos de trabajo;
3. División: Los datos en un hilo paralelo se dividen en partes utilizando la interfaz Spliterator;
4. Procesamiento: Cada hilo de trabajo en ForkJoinPool procesa su parte de los datos;
5. Fusión: Tras procesar los datos, los hilos de trabajo fusionan los resultados.
Ventajas de los Streams Paralelos
Mayor rendimiento es uno de los beneficios clave de los hilos paralelos, ya que permiten la distribución de tareas entre múltiples hilos, lo que resulta en un procesamiento más rápido en procesadores multinúcleo.
Además, la facilidad de uso de la API de hilos paralelos permite una integración sencilla en el código existente, eliminando la necesidad de una gestión compleja de hilos.
Asimismo, la escalabilidad es una ventaja significativa, ya que los hilos paralelos se ajustan automáticamente al número de núcleos de procesador disponibles, optimizando la ejecución de tareas de manera eficiente.
1. ¿Qué clase es utilizada por los hilos paralelos para controlar los hilos?
2. ¿Qué método se utiliza para crear un flujo paralelo?
3. ¿Qué hace la interfaz Spliterator en el contexto de los flujos paralelos?
¡Gracias por tus comentarios!