Concurrency 如何使用多核并行在Java中并发运行图形算法

Concurrency 如何使用多核并行在Java中并发运行图形算法,concurrency,java-8,executorservice,multicore,java.util.concurrent,Concurrency,Java 8,Executorservice,Multicore,Java.util.concurrent,我想在大型图上同时运行一个算法,使用多核并行。我已经做了一段时间了,但是还没有找到一个好的解决方案 这就是朴素的算法: W - a very large number double weight = 0 while(weight < W) - v : get_random_node_from(Graph) - weight += calculate(v) 重要的是,所有线程更新相同的I和weight 谢谢。好吧,你可以把权重封装成一个元素数组,这是这类东西的一种诀窍

我想在大型图上同时运行一个算法,使用多核并行。我已经做了一段时间了,但是还没有找到一个好的解决方案

这就是朴素的算法:

W - a very large number
double weight = 0

while(weight < W)

    - v : get_random_node_from(Graph)

    - weight += calculate(v)
重要的是,所有线程更新相同的
I
weight


谢谢。

好吧,你可以把
权重
封装成一个元素数组,这是这类东西的一种诀窍;即使是由java内部完成,如下所示:

weight[0] = weight[0] + calculate(v);
但这也有问题,因为您将并行运行它。由于
weight[0]
不是线程安全的,因此无法获得所需的结果。您可以使用某种类型的同步,但是java已经有了一个很好的解决方案:
DoubleAdder
,它在竞争环境(和多个CPU)中的扩展性要好得多

一个微不足道的小例子:

DoubleAdder weight = new DoubleAdder();

private static int calculate(int v) {
    return v + 1;
}


Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
            .parallel()
            .forEach(x -> {
                int y = calculate(x);
                weight.add(y);
            });

System.out.println(weight); // 54
然后是您将为此选择的随机化器的问题:
get\u random\u node\u from(Graph)
。实际上,您需要获得一个随机的
节点
,但同时您需要精确地获得所有节点一次。 但是,如果可以将所有节点展平到一个
列表中,您可能不需要它

这里的问题是,图形通常是以递归方式遍历的,您不知道它的确切大小:

while(parent.hasChildren) {
     traverse children and so on...
}

这将并行化坏数据流,您可以查看
拆分器#拆分器Unknownsize
。它将从
1024开始算术增长;这就是为什么我建议将节点扁平化为一个已知大小的列表;这将更好地并行化。

我不确定您想要完成什么-如果要使用Java流计算整个图的权重,您只需将流的每个元素都作为图的一个节点,使用map将其映射到权重,然后对流求和。这也应该是可parellizable的。让
权重
。您启动了几个
计算(v)
,但在第一个
权重+=calculate(v)
之后,权重
变为
=W
。是否应该取消其他计算,或者他们可以完成工作?如果他们能够完成他们的工作,他们可以并且应该将结果添加到
weight
?@AlexeiKaigorodov,只要
weight>W
所有过程都应该停止。我将编辑问题以添加更多详细信息。
Callable
传递给执行者不需要是lambda。它可以是实现
Callable
的任何类型,因此可以访问任何信息。感谢您的建议。但是,我已经尝试过了,并且遇到了同步问题(可能)并得到了InvalidOperationException。
while(parent.hasChildren) {
     traverse children and so on...
}