forEach 和 forEachOrdered在Java 8 Stream的区别
Stream.of("AAA","BBB","CCC").parallel().forEach(s->System.out.println("Output:"+s));
Stream.of("AAA","BBB","CCC").parallel().forEachOrdered(s->System.out.println("Output:"+s);
第二行输出的一直是:
AAA
BBB
CCC
而第一种输出的情况不确定。应为是并行处理。
其实两者完成的功能类似,主要区别在并行处理上,forEach是并行处理的,forEachOrder是按顺序处理的,显然前者速度更快。
parallel()
采用并行化来处理stream流;当普通stream流时,即:
Stream.of("AAA","BBB","CCC").forEach(s->System.out.println("Output:"+s));
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s);
forEach与forEachOrdered没有区别
对于forEach ,当stream 为parallel的时候,是多个线程,并行处理的。因此输出的数据顺序不能保证。
由于是并行处理,数据处理效率较高。
但是,对于操作共享变量的时候,需要注意安全问题,需要保证同步。
比如下面例子:
IntStream.range(0,1000).parallel().forEach(i->list.add(i)); System.out.println(list.size());
有可能会报错:Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException
或者会出现,list.size 不为1000
所以需要加同步锁来解决安全问题:
IntStream.range(0,1000).parallel().forEach(i->{lock.lock(); try { list.add(i); }finally { lock.unlock(); } }); System.out.println(list.size());
对于forEachOrdeed ,当stream 为parallel的时候,尽管是多个线程,并行处理的。但是还是会按照他source原有的顺序输出,,底层是通过happensbefore原则保证了它的内存可见性。(可以理解为相当于用volatile修饰了吧)
所以下面的代码并不会报错:
IntStream.range(0,1000).parallel().forEachOrdered(i->list.add(i)); System.out.println(list.size());
评论功能已关闭