当前位置:  开发笔记 > 编程语言 > 正文

进一步并行化两个Java parallelStream()的计算

如何解决《进一步并行化两个JavaparallelStream()的计算》经验,为你挑选了1个好方法。

我有一个方法可以并行计算列表中数字的平方并将它们相加:

public static double sumSquared(List values) {
    return values
            .parallelStream()
            .mapToDouble(d -> d * d)
            .sum();
}

假设存在一些双重列表,如何进一步并行化,例如

double result = sumSquared(list0) + (sumSquared(list1) * sumSquared(list2));

有优雅的方式吗?我想为每个列表操作启动单独的线程并没有多大帮助,因为它们使用相同的线程池.是否有意义或是否应如上所述计算结果?



1> Didier L..:

问题确实是即使sumSquared()并行处理数据,每个sumSquared()调用都是按顺序执行的.因此,这些列表仍然是逐个处理的,因此如果这些列表中的一些列表太小而无法分割到多个CPU,则会丢失CPU处理时间.

为避免这种情况,使用Java 8中的new CompletionStage/ CompletableFutureintroduction 并行运行整个计算:

// each sumSquared() is submitted immediately to the common pool
CompletionStage sumList0 = CompletableFuture.supplyAsync(() -> sumSquared(list0));
CompletionStage sumList1 = CompletableFuture.supplyAsync(() -> sumSquared(list1));
CompletionStage sumList2 = CompletableFuture.supplyAsync(() -> sumSquared(list2));

// as soon as sumList1 and sumList2 have both complete, their product is computed
CompletionStage prodSumList1and2 = sumList1.thenCombine(sumList2, (a, b) -> a * b);
// as soon as their product is computed and sumList0 is finished, the final sum is computed
CompletionStage result = sumList0.thenCombine(prodSumList1and2, Double::sum);

System.out.println(result.toCompletableFuture().get());

请注意,这使用公共池,默认情况下,该池使用所有CPU.因此,如果您只执行CPU繁重的操作,则使用自定义池可能无法提高性能,除非您有其他并行运行的作业.

例如,如果您的处理更多是I/O绑定或内存绑定,情况可能会有所不同.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有