Java 8新特性:并行流

1.概述

Java 8引入了Streams的概念,作为对数据执行批量操作的有效方式。并行Streams可以在支持并发的环境中获得。

这些流可以提高性能 - 以多线程开销为代价。

在本快速教程中,我们将介绍***Stream API的一个最大限制,**并了解如何使并行流与自定义 ThreadPool实例一起工作,或者 - 用一个库来处理这个问题 https://github.com/pivovarit/parallel-collectors。

2.并行流

让我们从一个简单的例子开始 - 在任何Collection类型上调用parallelStream方法- 这将返回一个可能并行的Stream


@Test

public void givenList_whenCallingParallelStream(){

List<Long> aList = new ArrayList<>();

Stream<Long> parallelStream = aList.parallelStream();

assertTrue(parallelStream.isParallel());

}

在这样的Stream中发生的默认处理使用ForkJoinPool.commonPool(),它是整个应用程序共享的线程池

3.自定义线程池

**我们实际上可以在处理时传递自定义ThreadPool

以下示例允许并行Stream使用自定义线程池来计算1到1,000,000之间的值之和,示例:


@Test
public void giveRangeOfLongs_Total()  throws InterruptedException, ExecutionException {

long firstNum = 1;
long lastNum = 1000000;

List<Long> aList = LongStream.rangeClosed(firstNum, lastNum).boxed().collect(Collectors.toList());

ForkJoinPool customThreadPool = new ForkJoinPool(4);

long actualTotal = customThreadPool.submit(() -> aList.parallelStream().reduce(0L, Long::sum)).get();

assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);

}

我们使用ForkJoinPool构造函数,并行级别为4.需要进行一些实验来确定不同环境的最佳值,但一个好的经验法则是根据CPU的核心数量选择数字。

接下来,我们处理并行Stream的内容,在reduce调用中将它们相加。

这个简单的例子可能无法证明使用自定义线程池的全部用处,但是在我们不希望将公共线程池与长时间运行的任务(例如,处理来自网络源的数据)联系起来的情况下,这些好处变得明显。,或者应用程序中的其他组件正在使用公共线程池

4.结论

我们简要介绍了如何使用自定义线程池运行并行Stream。在适当的环境中并且在正确使用并行度级别的情况下,可以在某些情况下获得性能提升。
image

欢迎大家关注公众号:「Java知己」,关注公众号,回复「1024」你懂得,免费领取 30 本经典编程书籍。关注我,与 10 万程序员一起进步。 每天更新Java知识哦,期待你的到来!

image

猜你喜欢

转载自blog.csdn.net/feilang00/article/details/87856573