Java and Spring development

Archive for the ‘Concurrency’ Category

Spring asynchronous support

with 3 comments

Spring 3 supports declarative concurrency support. At its simplest, you only need to specify in the Spring configuration file and add an @Async annotation above the method that you want to execute in an asynchronous process.

@Async
public void findBalanceAsync(final Account account) {
	accountRepository.findBalance(account);
}

See also this blog for step by step guide on how to execute a void method asynchronously.

In many cases you also want the response message from a method executed asynchronously. To achieve this, Spring returns a java.util.concurrent.Future object. All that’s required from the implementation is to create and return a new AsyncResult object like this:

@Async
public Future<Balance> findBalanceAsync(final Account account) {
	Balance balance = accountRepository.findBalance(account);
	return new AsyncResult<Balance>(balance);
}

Further, to retrieve the balance from this future object:

Balance balance = future.get();

If the method that’s executed asynchronously throws an exception, it will be wrapped inside an ExecutionException and throwed when the Future’s get method gets called.

Java EE 6 specification support

If you prefer to use the Java EE 6 specification, then you can replace Spring’s Async and AsyncResult classes with the corresponding classes in the javax.ejb package in the commons annotations 1.1 specification.

@javax.ejb.Asynchronous
public Future<Balance> findBalanceAsync(final Account account) {
	Balance balance = accountRepository.findBalance(account);
	return new javax.ejb.AsyncResult<Balance>(balance);
}

Configuring the task elements

The Spring container understand the javax.ejb classes without any configuration changes. You only need to add the commons annotation API on the classpath.

Spring’s task support can be configured with values like the thread pool and wich implementation you prefer to use. The easiest approach is to use the task namespace’s executor element. This element instantiates a ThreadPoolTaskExecutor object. This class implements the java.util.concurrent.Executor interface. Another option is declare your own bean like the ExecutorService bean below and let the annotation-driven task element reference to it. See example below:

<bean id="executorService" class="java.util.concurrent.Executors"
	factory-method="newFixedThreadPool">
	<constructor-arg value="10" />
</bean>

<task:executor id="threadPoolTaskExecutor" pool-size="10" />

<task:annotation-driven executor="executorService" />

Work with the underlying ExecutorService implementation

If you want to configure the ExecutorService object used by the Spring container after it’s initialized, then you can to do it programmatically as long as it’s a singleton bean. The first step is to retrieve the object with dependency injection like this:

@Inject
ExecutorService executorService;

Then cast it to a TreadPoolExecutor object and adjust the settings like the pool size showed below:

ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
threadPoolExecutor.setMaximumPoolSize(poolSize);
threadPoolExecutor.setCorePoolSize(poolSize);

An another example it can be useful to handle the underlying implementation is if you want to abort all work in the ExecutorService or ThreadPoolTaskExecutor’s queue. Then you can execute the shutdown method like this:

executorService.shutdown();

Conclusion

Spring’s asynchronous support abstracts away most of the complex threading logic for you and still provides full access to the implementation behind. It also supports the new async API in Java EE 6 without any configuration changes.

The code used in this article was developed in my work time at Redpill Linpro.


Redpill Linpro is the leading provider of Professional Open Source services and products in the Nordic region.

Written by Espen

March 8, 2010 at 00:44

Posted in Concurrency

Tagged with , , ,

Follow

Get every new post delivered to your Inbox.

Join 39 other followers