繁体   English   中英

Java ForkJoin Future似乎过早完成

[英]Java ForkJoin Future seems to finish prematurely

我对jsr166y库是完全陌生的,并且已经使用forkjoin库编写了一个例程,该例程可拆分查询并针对数据库副本同时运行查询。 我在下面放了一个片段。 SelectTask扩展了RecursiveTask。

ForkJoinExecutor fjPool;
    Future queryResultsFut = null;
      for (int i = 1; i <= lastBatchNum; i++) {

...

  SelectTask selectMatchesRecursiveTask = new SelectMatchesTask(loadBalancer.getDao(), thisRuleBatch, queryResults);
  queryResultsFut = fjPool.submit(selectMatchesRecursiveTask);
}

queryResultsFut.get();

调用get方法的目的是阻塞父线程,直到返回所有查询结果,以便可以对聚合结果进行处理。

我现在发现在CI环境中运行一段时间后,这种情况并不总是会发生。 如果数据库运行缓慢,那么即使任务仍在运行,线程也将继续运行。 在我看来,这似乎与我阅读的文档相矛盾。

也许我会以错误的方式来做这件事? 我应该扩展ForkJoinTask而不是RecursiveTask吗?

您可能根本不应该使用ForkJoin。 FJ框架是专为CPU密集型非阻塞任务并行性而设计的,但是您专门将其用于阻塞任务(外部数据库查询)。 我建议您使用普通的执行程序框架来尝试执行操作。

FJ唯一与您的问题匹配的方面是任务分解。 无论是通过简单的n路除法还是通过更复杂的递归策略,手动滚动都不会太困难。

RecursiveTask继承了它从ForkJoinTask获得的功能,因此扩展ForkJoinTask不会产生不同的效果。 请记住,每次提交时,都会返回一个不同的ForkJoinTask。 您调用fjPool.submit几次? 如果您做得更多,那么一旦获得您提交的最后一个任务,当最后一个任务完成时,queryResultsFut将完成(即从get返回)。

由于您现在正在处理ForkJoin池,因此应该在提交后而不是Future之前返回一个ForkJoinTask。 JF框架的主要目的是进行分而治之。 当您能够将一个问题分解为较小的类似问题,并行执行它们,然后组合结果并返回时,此方法将非常有用。

尝试使用另一种fork-join方法: http : //www.coopsoft.com/ar/ForkJoinArticle.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM