Java ForkJoin Future 似乎提前完成

标签 java multithreading concurrency threadpool

我对 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 路除法或更复杂的递归策略,手动实现这一点并不会太困难。

关于Java ForkJoin Future 似乎提前完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5250160/

相关文章:

java - void 是一种类型吗?

java - 多线程环境中的 boolean 值

c++ - C++中的静态初始化和线程安全

java - 为什么 StringBuffer#append 抛出 StringIndexOutOfBoundsException

java - CAPD远程监控系统

java - 如何正确使用 volatile 来杀死线程?

java - 将数据传递给正在运行的线程的正确方法是什么

具有内存排序的 C++ 原子增量

performance - 最佳进程数?

java - 下面的 java 代码在没有 volatile 的情况下是线程安全的吗?