【问题标题】:How to use Future and Callable in recursive method?如何在递归方法中使用 Future 和 Callable?
【发布时间】:2012-05-29 21:41:16
【问题描述】:

我正在尝试使用 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?

【问题讨论】:

    标签: recursion parallel-processing future executor callable


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:
          Future<MyResult> task = exec.submit(callable);
          return task.get();
      

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

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

      【讨论】:

        猜你喜欢
        • 2014-09-29
        • 2013-02-21
        • 2021-11-20
        • 2012-05-04
        • 1970-01-01
        • 2021-11-16
        • 2014-12-19
        • 2014-02-12
        • 1970-01-01
        相关资源
        最近更新 更多