在学习 Java 8 函数式编程的相关知识的时候,做了一个小练习题:
很简单啊,于是我键盘一挥,使用并行流写了如下代码
public static int parallelSumOfSquares(IntStream range) {
return range.parallel() //这里直接将流转化为并行流
.map(x -> x * x)
.sum();
}
然后呢,为了测试效果,我还准备将两个方法的结果做一下对比
(这里为了效果明显,就不用Assert断言了,积极推荐大家使用 Junit 测试方法)
public class TestParallel {
public static void main(String[] args) {
int[] values = new int[]{2, 3, 6, 22, 5};
IntStream range = IntStream.of(values);
int resultSequential = TestParallel.sequentialSumOfSquares(range);
int resultParallel = TestParallel.parallelSumOfSquares(range);
System.out.println("串行:" + resultSequential + ": 并行 :" + resultParallel);
}
//串行求列表数字的平方和
public static int sequentialSumOfSquares(IntStream range) {
return range.map(x -> x * x)
.sum();
}
// 并行流求列表数字的平方和
public static int parallelSumOfSquares(IntStream range) {
return range.parallel()
.map(x -> x * x)
.sum();
}
}
乍一看,有问题么?没有问题啊,编译器正常,连个警告都没有是不是?
没错,我也是这么想的。。。
然后运行,报错~
嗯。报错信息:流已经被操作或关闭
报错位置:调用 parallelSumOfSquares 方法的时候
我们来看一下报错位置的代码
哦,在调用第二个方法的时候,我的流已经被使用了,这样是不可以的。
也就是说:一个 Stream 只可以使用一次
原因找到了,我们改一下代码
IntStream rangeSequ = IntStream.of(values);
IntStream rangePara = IntStream.of(values);
int resultSequential = TestParallel.sequentialSumOfSquares(rangeSequ);
int resultParallel = TestParallel.parallelSumOfSquares(rangePara);
这次OK了,结果正确:串行: 558: 并行 :558
结语:每踩过的一个坑无论大小都是值得记录的,简单也是积累