1

我正在尝试使用 Future 和 Callable 将 dfs 递归方法转换为并行以提高效率。但不知道如何正确地做到这一点。这是代码:

public MyResult compute(MyTree tree, int depth, ExecutorService exec) {
    if (depth >= 3) {
        Callable<MyResult> callable = new Callable<MyResult>() {
            @Override
            public MyResult call() throws Exception {
                return compute(tree, 0, exec);
            }
        };
        Future<MyResult> task = exec.submit(callable);
        return task.get();
    }
    else {
        MyResult result = new MyResult();
        if (something) {
            tree = tree.leftChild;
            result = compute(tree,depth+1,exec);
        }
        else if (something else){
            tree = tree.rightChild;
            result = compute(tree,depth+1,exec);
        }
        else
            return result;
    }
}

我期望做的是递归方法将继续计算而不等待task.get()的返回值。因此,每当它进入深度 3 时,它都会提交一个未来任务,然后返回计算另一个子树,同时该任务将计算自己的子树。

但是,我发现这个方法仍然是顺序的,而不是并行的。(我每次调用方法时都打印出深度,结果和没有使用future和executor的方法一样,而且总是比较慢。)

我相信这不是使用 Future 和 Callable 的正确方法,我找到了一些示例,但它们没有使用递归方法。最常见的例子是有一个 Future List> 的列表,并且每次提交一个任务,然后在另一个循环中迭代 Future 列表。

有谁知道如何以递归方法实现 Future 和 Executor ?

4

2 回答 2

1

您可能对 Java 1.7 ForkJoinPool 更满意,它专门针对递归分而治之。

于 2012-05-29T21:43:03.077 回答
1
    Future<MyResult> task = exec.submit(callable);
    return task.get();

这段代码相当于调用callable.run(). Future.get() 阻塞输出。

也许这个例子太简单了。看来逻辑永远不需要处理多个子树。如果您需要来自同一节点的多个递归调用,您可以将它们全部提交为Callables 并在一个单独的循环中等待它们,正如您所提到的。(当然,您的 ExecutorService 也需要有多个线程。)

于 2012-05-29T23:29:59.923 回答