Java 8新特性(5) Parallel Streams
流操作可以是顺序的,也可以是并行的。顺序操作通过单线程执行,而并行操作则通过多线程执行。
下面的例子就演示了如何使用并行流进行操作来提高运行效率,代码非常简单。
首先我们创建一个大的 list,里面的元素都是唯一的:
int max = 1000000;
List<String> values = new ArrayList<>(max);
for (int i = 0; i < max; i++) {
UUID uuid = UUID.randomUUID();
values.add(uuid.toString());
}
现在,我们测量一下对这个集合进行排序所使用的时间。
顺序排序
long t0 = System.nanoTime();
long count = values.stream().sorted().count();
System.out.println(count);
long t1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
System.out.println(String.format("sequential sort took: %d ms", millis));
// sequential sort took: 899 ms
并行排序
long t0 = System.nanoTime();
long count = values.parallelStream().sorted().count();
System.out.println(count);
long t1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
System.out.println(String.format("parallel sort took: %d ms", millis));
// parallel sort took: 472 ms
如你所见,所有的代码段几乎都相同,唯一的不同就是把 stream() 改成了 parallelStream(), 结果并行排序快了 50%。
流可以并行执行,在大量输入元素上可以提升运行时的性能。并行流使用公共的 ForkJoinPool,由 ForkJoinPool.commonPool() 方法提供。底层线程池的大小最大为五个线程 -- 取决于 CPU 的物理核数。
ForkJoinPool commonPool = ForkJoinPool.commonPool();
System.out.println(commonPool.getParallelism()); // 3
在我的机器上,公共池默认初始化为 3。这个值可以通过设置下列 JVM 参数来增减:
-Djava.util.concurrent.ForkJoinPool.common.parallelism=5
集合支持 parallelStream()
方法来创建元素的并行流。或者你可以在已存在的数据流上调用衔接方法 parallel()
,将串行流转换为并行流。
总之,并行流对拥有大量输入元素的数据流具有极大的性能提升。但是要记住一些并行流的操作,例如 reduce
和 collect
需要额外的计算(组合操作),这在串行执行时并不需要。
https://wizardforcel.gitbooks.io/modern-java/content/ch2.html
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com
文章标题:Java 8新特性(5) Parallel Streams
文章字数:515
本文作者:Bin
发布时间:2019-03-13, 21:15:22
最后更新:2019-08-06, 00:07:35
原始链接:http://coolview.github.io/2019/03/13/Java8/Java%208%E6%96%B0%E7%89%B9%E6%80%A7(5)%20Parallel%20Streams/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。