hace la operación mapa de estado de los elementos del proceso de flujo ordenados en forma determinista?

Amarnath Harish:

Estoy leyendo sobre Java API de Secuencia y me encontré con el siguiente aquí :

La operación forEachOrderedelementos procesos en el orden especificado por la corriente, independientemente de si la corriente es ejecutado en serie o paralelo. Sin embargo, cuando una corriente se ejecuta en paralelo, la operación de mapa de procesos elementos de la secuencia especificada por el tiempo de ejecución de Java y el compilador. En consecuencia, el orden en el que la expresión lambda e -> { parallelStorage.add(e); return e; }agrega elementos a la List parallelStoragepueden variar cada vez que se ejecuta el código. Para obtener resultados deterministas y predecibles, aseguran que los parámetros de expresión lambda en las operaciones de transmisión no son con estado.

He probado el siguiente código y, de hecho, funciona como se ha mencionado:

public class MapOrdering {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    List < String > serialStorage = new ArrayList < > ();

    System.out.println("Serial stream:");
    int j = 0;
    List < String > listOfIntegers = new ArrayList();
    for (int i = 0; i < 10; i++) listOfIntegers.add(String.valueOf(i));

    listOfIntegers.stream().parallel().map(e - > {
      serialStorage.add(e.concat(String.valueOf(j)));
      return e;
    }).forEachOrdered(k - > System.out.println(k));;
    /* 
    // Don't do this! It uses a stateful lambda expression.
    .map(e -> { serialStorage.add(e); return e; })*/

    for (String s: serialStorage) System.out.println(s);
  }
}

salida

corriente de serie: 0 1 2 3 4 5 6 7 8 9 null null 80 90 50 40 30 00

preguntas:

  1. La salida cambia cada vez que funciono esto. ¿Cómo me aseguro de que la operación mapa de estado se ejecuta en orden.
  2. mapa es una operación intermedia y sólo comienza elementos de procesamiento hasta que comience el funcionamiento del terminal. Dado que se ordena una operación de terminal, ¿por qué es una operación de mapa no ordenadas , y tiende a cambiar los resultados cada vez que cuando se trabaja con la operación de estado?
Eugene:

Tienes suerte de ver que serialStoragetiene todos los elementos que usted piensa que va, después de todo lo que se agregó desde varios subprocesos múltiples elementos a un no-thread-safe colección ArrayList. Usted podría haber visto fácilmente nulls o unos Listque no tienen todos los elementos. Pero incluso cuando se agrega una Listque es seguro para subprocesos - no hay absolutamente ningún orden en que se puede confiar en esa lista.

Esto se menciona explícitamente en la documentación bajo los efectos secundarios , y operaciones intermedias debe ser libre de efectos lado.

Básicamente hay dos ordenamientos: orden de procesamiento (operaciones intermedias) y fin encuentro . El último es conservado (si es tiene uno, para empezar y transmitir operaciones intermedias no romperlo - por ejemplo unordered, sorted).

Para el procesamiento no se especifica, es decir, todas las operaciones intermedias procesarán los elementos en el orden que les da la gana. Para el encuentro (el que se ve desde un terminal de operación) se preservador del pedido inicial.

Pero incluso si las operaciones de no tienen que preservar el orden inicial, por ejemplo forEachvs forEachOrderedo cuando recoja a una Set; por supuesto leer la documentación, por lo general establece claramente este aspecto.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=177834&siteId=1
Recomendado
Clasificación