Java parallelStream没有显示正确的结果

时间:2017-12-08 16:56:01

标签: java java-8 java-stream

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

    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的正确性。 感谢

3 个答案:

答案 0 :(得分:4)

我认为您的代码遇到了count()方法的问题。由于parallelStream将尝试同时执行任务。此方法应为synchronized,或者您可以将totaleven设为Atomtic Integer。希望它有所帮助。

答案 1 :(得分:3)

您可以使用终端操作Stream:count

,而不是使用forEach递增计数器

例如

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

totaleven需要更改为数据类型long或者应用了cast。

答案 2 :(得分:2)

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