Java ExecutorService Future::变得非常慢

Java ExecutorService Future::变得非常慢,java,multithreading,performance,future,executorservice,Java,Multithreading,Performance,Future,Executorservice,我正在对一个相当复杂的程序进行并行化,以加快速度。为此,我大部分时间使用ExecutorService。直到现在,它工作得相当好,但后来我注意到,只有一行代码使我的程序运行速度减半。这是带有exactScore.get()的行 我不知道为什么,但有时需要超过0.1秒才能获得未来对象的双倍值 为什么会这样?我如何处理它,使它运行得更快?有没有一种方法可以在多线程处理时直接在Double[]中写入? 谢谢 int processors=Runtime.getRuntime().availablePr

我正在对一个相当复杂的程序进行并行化,以加快速度。为此,我大部分时间使用
ExecutorService
。直到现在,它工作得相当好,但后来我注意到,只有一行代码使我的程序运行速度减半。这是带有
exactScore.get()
的行

我不知道为什么,但有时需要超过0.1秒才能获得未来对象的双倍值

为什么会这样?我如何处理它,使它运行得更快?有没有一种方法可以在多线程处理时直接在
Double[]
中写入? 谢谢

int processors=Runtime.getRuntime().availableProcessors();
ExecutorService=Executors.newFixedThreadPool(处理器);
//初始化输出
Double[]预排序得分=新的Double[sortedHeuScores.length];
for(int i=0;i
这是意料之中的。那不是“慢”了;它只是在做它的工作

从javadoc获取:

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

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

通过调用
get()
您可以表达:我不介意现在就等待,直到“隐藏”在未来的计算结果可用

因此:您必须后退一步,再次查看代码;了解你不同的“活动线程”是如何工作的;以及他们如何/何时重归于好

我想到一个想法:现在,你正在循环中创建你未来的对象;在您创建了未来之后,您可以直接对其调用
get()
。这与创造多重未来的想法完全矛盾。换言之:与其走:

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
换言之:让你的未来真正做到并行;而不是强制执行顺序处理

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

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


这里还有一个非常重要的收获:不要盲目地使用一些“碰巧”能工作的代码。编程的本质之一是理解源代码中使用的每一个概念。在运行代码并发现“哦,
get()
会让事情变慢”之前,您应该非常清楚代码正在做什么。因此,如果我不尝试将其放入for循环中,会更好吗?因为如果我理解正确的话,在我的exactScor.get完成之前,其他执行器将无法获得作业(因此这次没有新的多线程)。请查看我的各种更新。它可以帮助将事物分成两个循环;但这确实取决于一些事情,而不仅仅是简单的问答式讨论。
foreach X
  create future X.i

foreach X
  wait/get for future X.i