Java parallel Stream没有显示正确的结果

Java parallelStream not showing correct result

本问题已经有最佳答案,请猛点这里访问。

我正在对Java GracaGATE操作进行一些性能评估,以对集合进行迭代。我正在评估streamparallelStream的性能。但我发现,大多数时候,parallelStream的输出都是错误的。例如,在下面的代码中,我从parallelStream得到错误的输出的时间超过了80%:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    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的正确性?谢谢


我认为您的代码与count()方法有问题。因为parallelStream将尝试同时执行任务。这个方法应该是synchronized,或者可以将totaleven设为原子整数。希望有帮助。


您可以使用终端操作流:count,而不是使用foreach递增计数器。

例如

1
2
3
totaleven = randomList.stream().filter(e -> e % 2 ==0).count();
totaleven = 0;
totaleven = randomList.parallelStream().filter(e -> e % 2 ==0).count();

totalEven需要更改为数据类型long或应用强制转换。


并行流结果有什么问题?如果它太小,那么很可能您对totaleven++有问题,因为它不是线程安全的。使用atomicinteger或任何其他线程安全解决方案。