andPat andPat - 4 months ago 25
Java Question

Parallel for with Spring Asynchronous execution

I want to iterate over a list of elements and execute operations on them asynchronously (in a parallel way).

Here is my code:

@Autowired
ElemManager elemManager;

...
List<Elem> elems = new ArrayList<>();

for ( Elem elem : elems ) {
System.out.println(elemManager.doSomething(elem).get());
}


where ElemManager is:

public class ElemManager {

@Async
public Future<String> doSomething( Elem elem ) {
// do something
return "done";
}


I have also created a thread pool in spring context and enabled asynchronous execution so:

@Configuration
@EnableAsync
public class TaskConfiguration implements AsyncConfigurer {

@Override
public Executor getAsyncExecutor() {
final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setMaxPoolSize( 5 );
threadPoolTaskExecutor.setAwaitTerminationSeconds( 60 );
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}

}


Am I missing something? Is it the correct way to parallel execute a method through Spring Asynchronous execution support?

Answer

You're not actually invoking that using Spring. You're just invoking it like a plain old method.

But aside from this, calling Future.get() means that you wait for the future to complete.

Add the Futures to a list first, and then call .get() on them in turn:

List<Future<?>> futures = new ArrayList<>();
for ( Elem elem : elems ) {
  futures.add(elemManager.doSomething(elem));
}
for (Future<?> future : futures) {
  System.out.println(future.get());
}
Comments