Java 8新特性(5) Parallel Streams

  1. 顺序排序
  2. 并行排序

流操作可以是顺序的,也可以是并行的。顺序操作通过单线程执行,而并行操作则通过多线程执行。

下面的例子就演示了如何使用并行流进行操作来提高运行效率,代码非常简单。

首先我们创建一个大的 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(),将串行流转换为并行流。

总之,并行流对拥有大量输入元素的数据流具有极大的性能提升。但是要记住一些并行流的操作,例如 reducecollect 需要额外的计算(组合操作),这在串行执行时并不需要。

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" 转载请保留原文链接及作者。

目录