我完全不熟悉jsr166y库,并且使用forkjoin库编写了一个例程,该库分割了一个查询并且同时运行它与数据库副本。我在下面放了一个片段。 SelectTask扩展了RecursiveTask。Java ForkJoin Future似乎过早完成
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吗?
感谢您的启发。您是否会知道执行程序框架是否包含将视为“假设所有已完成”方面的内容,这些方面我都假设为fork连接的设计目的? – barrymac 2011-03-10 11:38:03
其实它看起来像我应该使用Phaser来实现带有ForkJoinPool的CyclicBarrier:http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/Phaser.html – barrymac 2011-03-10 11:50:08
不知道为什么你想要等待它们全部完成,但是'ExecutorService.invokeAll(Collection>)'返回'List >'的结果。当你遍历它并获得每个将来阻塞的结果,直到未来完成为止,因此,在完成所有工作之前,不要完成迭代。如果你想以完成顺序得到结果,你可以使用'CompletionService'。 –
2011-03-10 23:00:43