您的位置:首页 > 编程语言 > Java开发

《Java in Action》-1 第7章 并行处理数据与性能

2016-10-05 11:13 155 查看

第7章 并行处理数据与性能

7.1 并行流

可以通过对收集源调用parallelStream方法来把集合转换为并行流。并行流就是一个把内容分为多个数据块,并用不同的线程分别处理每个数据块的流。

例子:计算1到n所有数字的和

public static long sequentialSum(long n) {

return Stream.iterate(1L, 1 -> i+1)

.limit(n)

.reduce(0L,Long :: sum);

}

7.1.1 将顺序流装换为并行流

public static long sequentialSum(long n) {

return Stream.iterate(1L, 1 -> i+1)
.limit(n)
.parallel()
.reduce(0L,Long :: sum);
}
只需要调用sequential方法就可以把它变成顺序流。

7.1.2 测量流性能

7.1.3 正确使用并行流

共享可变状态会影响并行流以及并行计算,记录要避免共享可变状态,确保并行Stream得到正确的结果。

7.1.4 高效使用并行流

7.2 分支/合并框架

分支/合并框架的目的是以递归方式将可以并行的任务拆分为更小的任务,然后将每个子任务的结果合并起来生成整体结果。它是ExecutorService接口的一个实现,它把子任务分配给线程池(称为ForkJoinPool)中的工作线程。

7.2.1 使用RecursiveTask

创建RecursiveTask<R>的一个子类,其中R是并行化任务产生的结果类型,只需实现唯一的抽象方法compute

protected abstract R compute();

然后创建一个新的ForkJoinPool,并把任务传给它的调用方法。

new ForkJoinPool().invoke(task);

7.2.2 使用分支/合并框架的最佳做法

7.2.3 工作窃取

7.3 Spliterator

Spliterator,可分迭代器,用于遍历数据源中的元素,但它是为了并行执行而设计的。

7.4 小结

*内部迭代让你可以并行处理一个流,而无需在代码中显示使用和协调不同的线程

*虽然并行处理一个流很容易,却不能保证程序在所有情况下都运行得更快。并行软件的行为和性能有时是违反直觉的,因此一定要测量,确保你并没有吧程序拖得更慢。

*向并行流那样对一个数据集并行执行操作可以提升性能,特别是要处理的元素数据庞大,或处理单个元素特别耗时的时候

*从性能角度来看,使用正确的数据结构,如尽可能利用原始流而不是一般化的流,几乎总是比尝试进行并行化某些操作更为重要。

*分支/合并框架让你得以用递归方式将可以并行的任务拆分为更小的任务,在不同的线程上执行,然后将各个子任务的结果合并起来生成整体结果

*Spliterator定义了并行流如何拆分它要遍历的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: