Recursion 如何在递归方法中使用Future和Callable?

Recursion 如何在递归方法中使用Future和Callable?,recursion,parallel-processing,future,executor,callable,Recursion,Parallel Processing,Future,Executor,Callable,我正在尝试使用Future和Callable将dfs递归方法转换为并行方法,以提高效率。但我不知道如何做对。代码如下: public MyResult compute(MyTree tree, int depth, ExecutorService exec) { if (depth >= 3) { Callable<MyResult> callable = new Callable<MyResult>() { @Ove

我正在尝试使用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;
    }
}
公共MyResult计算(MyTree树、int深度、ExecutorService exec){
如果(深度>=3){
Callable Callable=new Callable(){
@凌驾
公共MyResult调用()引发异常{
返回compute(树,0,exec);
}
};
未来任务=执行提交(可调用);
return task.get();
}
否则{
MyResult=新的MyResult();
如果(某物){
tree=tree.leftChild;
结果=计算(树,深度+1,执行);
}
如果(其他事情){
tree=tree.rightChild;
结果=计算(树,深度+1,执行);
}
其他的
返回结果;
}
}
我希望递归方法能够继续计算,而不必等待task.get()的返回值。因此,无论何时进入深度3,它都会提交一个未来的任务,然后返回计算另一个子任务,而该任务将同时计算自己的子树

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

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


有人知道如何在递归方法中实现Future和Executor吗?

您可能更喜欢Java 1.7 ForkJoinPool,它专门针对递归分治。

Future task=exec.submit(可调用);
    Future<MyResult> task = exec.submit(callable);
    return task.get();
return task.get();
此代码相当于调用
callable.run()
。输出上的Future.get()块

也许这个例子太简单了。逻辑似乎永远不需要处理多个子树。如果您需要来自同一节点的多个递归调用,您可以将它们作为
Callable
s提交,并在一个单独的循环中等待它们,如您所述。(当然,Executor服务也需要有多个线程。)