我对 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/