Java ForkJoin Future seems to finish prematurely
I'm totally new to the jsr166y library and I've written a routine using the forkjoin library that splits up a query and runs it again开发者_如何学编程st database replicas concurrently. I've put a snippet below. The SelectTask extends 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();
The call to the get method is intended to block the parent thread until all query results are returned so that processing can commence on the aggregated results.
I've discovered now after some time running in a CI environment that this does not always happen. When there is a slow database then then thread will continue even if tasks are still running. This seems to me to contradict the documentation I read.
Perhaps I am going about this the wrong way? Should I extend ForkJoinTask instead of RecursiveTask?
You probably shouldn't be using ForkJoin for this at all. The FJ framework is specifically designed for CPU intensive non-blocking task parallelism, but you are specifically using it for blocking tasks (external db queries). I would suggest you use the normal executor framework for what you are trying to do.
The only aspect of FJ that matches your problem is the task decomposition. This though isn't going to be too difficult to roll by hand, either by a simple n-way division or by a more sophisticated recursive strategy.
RecursiveTask inherits it's get functionality from ForkJoinTask so extending ForkJoinTask wouldnt have a different effect. Keep in mind each time you submit you will get a different ForkJoinTask returned. How many times are you invoking fjPool.submit? If you are doing it more then once you will get the last task you submitted and thus queryResultsFut will complete (ie return from the get) when the last task completes.
Since you are dealing now with a ForkJoin pool you should expect back a ForkJoinTask after submitting instead of a Future. The main purpose of the JF framework is for divide and conquer processing. It is most useful when you are able to break up a problem into smaller similar problems, execute them in parallel then combining the results and returning.
Try using another fork-join method: http://www.coopsoft.com/ar/ForkJoinArticle.html
精彩评论