java - transmision - puerto paralelo
¿Por qué la secuencia paralela se recopila secuencialmente en Java 8? (2)
¿Por qué
forEach
imprime números en orden aleatorio, mientras que
collect
siempre recolecta elementos en orden original, incluso desde un flujo paralelo?
Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8};
List<Integer> listOfIntegers = new ArrayList<>(Arrays.asList(intArray));
System.out.println("Parallel Stream: ");
listOfIntegers
.stream()
.parallel()
.forEach(e -> System.out.print(e + " "));
System.out.println();
// Collectors
List<Integer> l = listOfIntegers
.stream()
.parallel()
.collect(Collectors.toList());
System.out.println(l);
Salida:
Parallel Stream:
8 1 6 2 7 4 5 3
[1, 2, 3, 4, 5, 6, 7, 8]
Aquí hay dos tipos diferentes de "pedidos", lo que hace que la discusión sea confusa.
Un tipo es el
orden de encuentro
, que se define en la
documentación de
las
transmisiones
.
Una buena manera de pensar en esto es el orden
espacial
o de
izquierda a derecha
de los elementos en la colección de origen.
Si la fuente es una
List
, considere que los elementos anteriores están a la izquierda de los elementos posteriores.
También hay un orden de procesamiento o temporal , que no está definido en la documentación, pero que es el orden de tiempo en el que los diferentes hilos procesan los elementos. Si los elementos de una lista están siendo procesados en paralelo por diferentes hilos, un hilo podría procesar el elemento más a la derecha de la lista antes del elemento más a la izquierda. Pero la próxima vez podría no serlo.
Incluso cuando los cálculos se realizan en paralelo, la mayoría de los
Collectors
y algunas operaciones de terminal se organizan cuidadosamente para preservar el
orden de encuentro
desde el origen hasta el destino, independientemente del
orden temporal
en el que diferentes hilos podrían procesar cada elemento.
Tenga en cuenta que la
forEach
terminal
forEach
no
conserva el orden de encuentro.
En cambio, lo ejecuta cualquier hilo que produzca el siguiente resultado.
Si desea algo como
forEach
que conserve el orden de encuentro, use
forEachOrdered
en
forEachOrdered
lugar.
Consulte también las Preguntas frecuentes de Lambda para obtener más información sobre los problemas de pedidos.
El
método
Collectors.toList
especifica que el
Collector
devuelto agrega elementos a la lista en orden de encuentro.
Devoluciones:
un recopilador que recopila todos los elementos de entrada en una lista, en orden de encuentro
No importa si el
Stream
es paralelo;
El orden se conserva.
Además, al mirar el código fuente de
Collectors
, el
Collector
devuelto llama a
addAll
en una
ArrayList
cuando se fusiona, y eso conserva el orden.
Por ejemplo, si un hilo tiene {1, 2} y el siguiente hilo tiene {3, 4}, entonces la llamada a
addAll
produce {1, 2, 3, 4}.
Además, el
Collector
devuelto no tiene la característica
UNORDERED
.