我正在对Java操作进行一些性能评估,以迭代集合。我正在对性能stream和parallelStream进行评估。但是我发现parallelStream的输出大多数时候都是错误的。例如,在下面的代码中,超过80%的时间来自parallelStream的输出是错误的:
public class ParallelStreamPerformance {
static int totaleven = 0;
public static void main(String[] args) {
List<Integer> randomList = new ArrayList<>();
Random rnd = new Random();
for(int i = 0 ;i < 1000;i++) {
int r = rnd.nextInt(500000);
randomList.add(r);
}
long s1 = System.currentTimeMillis();
randomList.stream().filter(e -> e%2 ==0).forEach(e -> count());
System.out.println("Even: "+totaleven);
long e1 = System.currentTimeMillis();
System.out.println(e1 - s1);
totaleven = 0;
long s2 = System.currentTimeMillis();
randomList.parallelStream().filter(e -> e%2 ==0).forEach(e -> count());
System.out.println("Even: "+totaleven);
long e2 = System.currentTimeMillis();
System.out.println(e2 - s2);
}
public static void count() {
totaleven++;
}
}我的问题是:我是否以错误的方式使用parallelStream?有没有办法确保parallelStream的正确性。谢谢
发布于 2017-12-08 17:00:19
我认为您的代码与count()方法有问题。因为parallelStream将尝试并发执行任务。这个方法应该是synchronized,或者您可以将totaleven作为Atomtic。希望能帮上忙。
发布于 2017-12-08 17:20:20
不使用forEach来增加计数器,您可以使用终端操作溪流:计数
例如
totaleven = randomList.stream().filter(e -> e % 2 ==0).count();
totaleven = 0;
totaleven = randomList.parallelStream().filter(e -> e % 2 ==0).count();总计甚至需要更改为数据类型长或转换应用。
发布于 2017-12-08 17:01:38
并行流结果有什么问题?如果它太小,那么您很可能对totaleven++有问题,因为它不是线程安全的。使用AtomicInteger或任何其他线程安全解决方案。
https://stackoverflow.com/questions/47718840
复制相似问题