我在阅读有关Java流API和我遇到以下位置:
操作
forEachOrdered
在由流指定,而不管流是否被以串行或并行执行的顺序处理的元件。然而,当流是并行执行的,在地图上的操作处理由Java运行时和编译器中指定的流的元素。因此,为了在其中λ表达式e -> { parallelStorage.add(e); return e; }
添加元素添加到List
parallelStorage
可以改变每次代码运行时间。确定性和可预测的结果,确保在流操作该lambda表达式参数不状态。
我测试了下面的代码,事实上,它的工作原理提到:
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);
}
}
产量
串行流:0 1 2 3 4 5 6 7 8 9空空80 90 50 40 30 00
问题:
你有幸运地看到serialStorage
了所有的元素,你觉得会的,毕竟你是从多个线程多个元素添加到一个非线程安全的集合ArrayList
。你可以很容易地看到null
S或A List
不具备的所有元素。但是,即使当你添加一个List
是线程安全的-是绝对没有为了使您可以在该列表中的依靠。
这是在文档中明确提到的副作用,以及中间业务应无侧效应。
基本上有两种排序:处理顺序(中间操作)和遭遇顺序。最后一个被保留(如果它是有一个开始和流中间操作不会打破它-例如unordered
,sorted
)。
处理顺序未指定,这意味着所有的中间业务将处理在他们觉得任何顺序相同的元件。遭遇顺序(从终端操作看到一个)将保护者的初始顺序。
但是,即使终端操作不必保留最初的订单,例如forEach
VS forEachOrdered
或当你收集到Set
; 当然,阅读文档,它通常明确指出这个方面。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句