I am in the situation where I have a collection of objects and every object has to run an expensive method that takes about 5-10 seconds to complete.
How can I run all methods in parallel and check the status periodically?
I tried to use the @Async annotation with a Future response, but nothing changed.
public static void populate(String marketId) {
//irrelevant code removed
List<Company> companies = mongo().find(new Query(c), Company.class);
List<Future> futures = new ArrayList<Future>();
for(Company comp : companies) {
futures.add(comp.updateData(market));
}
}
@Async
public Future<Boolean> updateData(Market market) {
//do my slow logic here
return new AsyncResult(false);
}
Is the ThreadPoolTaskExecutor the way to go?
I'm a bit confused as to the reasons you use AsyncResult (and which implementation... ejb?). If I'm not mistaken, it will not work that way, as (from what I know) AsyncResult is connected to the bean and @Asyncronous annotation making the response from a specific bean method assyncronous. But if used inside an object, it would be effectively sequential.
What you need here is a normal Future. If so, you need to actually run these futures in an executor and than wait until they finish by calling future.get(). A nice tutorial on that you can find here: http://java.dzone.com/articles/javautilconcurrentfuture
You can also look into Akka. Actor model is my personal favourite, as you can simply spawn a bunch of workers, tell them what to do, and let them let you know once they're done with their job. Still it might be an overkill if you only have a simple task at hand, depends on your style.
of cause this makes sense if you need to get some actual return from those futures. If they're void, and you just need a thread to run some side-effects somewhere else, than there's no point in doing it that way, and you can simply use runnables and executor. Something similar to this: wait until all threads finish their work in java