java - ExecutorService Future::变得非常慢

标签 java multithreading performance future executorservice

我正在并行化一个非常复杂的程序以使其更快。为此,我大部分时间使用 ExecutorService。到目前为止,它运行得很好,但后来我注意到,仅仅一行代码就可以让我的程序运行速度减半。这是带有 exactScore.get() 的行。

我不知道为什么,但有时需要超过 0.1 秒才能获取 Future 对象的 double 值。

这是为什么呢?我该如何处理它运行得更快?有没有办法在多线程时直接在Double[]中写入? 谢谢

int processors = Runtime.getRuntime().availableProcessors();
    ExecutorService service = Executors.newFixedThreadPool(processors);

    // initialize output
    Double[] presortedExScores = new Double[sortedHeuScores.length];

    for(int i =0; i < sortedHeuScores.length; i++ ){
        final int index = i;
        final Collection<MolecularFormula> formulas_for_exact_method = multimap.get(sortedHeuScores[i]);
        for (final MolecularFormula formula : formulas_for_exact_method){
            Future<Double> exactScore = service.submit(new Callable<Double>() {
                @Override
                public Double call() throws Exception {
                    return getScore(computeTreeExactly(computeGraph(formula)));
                }
            });
            presortedExScores[index] = exactScore.get();
        }

    }

最佳答案

这是可以预料的。那么它并不是“慢”,而是“慢”。它只是在做它的工作。

来自 get() 的 javadoc :

如有必要,等待计算完成,然后检索其结果。

长话短说:您似乎不理解代码中使用的概念。 future 的理念是它在 future 的某个时刻做事。

通过调用 get() 你可以表达:我不介意现在就等待,直到 Future“背后”的计算结果变得可用。

因此:你必须退后一步,再次查看你的代码;了解不同的“Activity 线索”如何真正发挥作用;以及他们如何/何时回到一起。

想到的一个想法:现在,您正在循环中创建 Future 对象;在创建 Future 后,立即对其调用 get() 。这完全违背了创建多个 Future 的想法。换句话说:而不是去:

foreach X
  create future X.i
  wait/get future X.i

你可以做类似的事情

foreach X
  create future X.i

foreach X
  wait/get for future X.i

换句话来说:让你的 future 真正并行地做事;而不是强制顺序处理。

如果这“不够”帮助,那么正如所说的:你必须审视你的整体设计,并确定是否有办法进一步“分解”事物。现在所有的 Activity 都“紧密地”一起发生;令人惊讶的是:当你同时做很多工作时,这需要时间。但正如您可能猜到的那样:这样的重新设计可能需要大量工作;如果不了解更多有关您的问题/代码库的信息,这几乎是不可能的。

更复杂的方法是,您编写代码,其中每个 Future 都有一种表达“我完成了”的方式 - 那么您将“仅”启动所有 Future;并等到最后一个回来。但正如所说;我无法在这里为您设计完整的解决方案。

这里另一个非常重要的要点:不要盲目地使用一些“碰巧”起作用的代码。编程的本质之一是理解源代码中使用的每个概念。 运行代码并发现“哦,get() 使事情变慢”之前,您应该非常清楚代码在做什么。

关于java - ExecutorService Future::变得非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41684447/

相关文章:

java - 方法中的参数从枚举请求常量 - 这些方法如何只接受特定常量?

java - 从线程外部调用正在运行的线程中的方法

c# - 来自封闭 block 的变量在匿名函数中变为空

c++ - 如何决定是否使用超线程?

java - 给定一个数组,找到总和为值 k 的所有子集

java - 更改第三方JAR的安全权限?

java - 编译器错误但程序执行正常

c++ - 同步访问分配的内存

c - 测量 C/C++ 应用程序中总上下文切换的最佳方法是什么?

mysql - 程序更新记录慢