Introduction The Spring TaskExecutor abstraction

4.3.9.RELEASE Spring Framework 757

34. Task Execution and Scheduling

34.1 Introduction

The Spring Framework provides abstractions for asynchronous execution and scheduling of tasks with the TaskExecutor and TaskScheduler interfaces, respectively. Spring also features implementations of those interfaces that support thread pools or delegation to CommonJ within an application server environment. Ultimately the use of these implementations behind the common interfaces abstracts away the differences between Java SE 5, Java SE 6 and Java EE environments. Spring also features integration classes for supporting scheduling with the Timer , part of the JDK since 1.3, and the Quartz Scheduler http:quartz-scheduler.org . Both of those schedulers are set up using a FactoryBean with optional references to Timer or Trigger instances, respectively. Furthermore, a convenience class for both the Quartz Scheduler and the Timer is available that allows you to invoke a method of an existing target object analogous to the normal MethodInvokingFactoryBean operation.

34.2 The Spring TaskExecutor abstraction

Spring 2.0 introduces a new abstraction for dealing with executors. Executors are the Java 5 name for the concept of thread pools. The executor naming is due to the fact that there is no guarantee that the underlying implementation is actually a pool; an executor may be single-threaded or even synchronous. Spring’s abstraction hides implementation details between Java SE 1.4, Java SE 5 and Java EE environments. Spring’s TaskExecutor interface is identical to the java.util.concurrent.Executor interface. In fact, its primary reason for existence was to abstract away the need for Java 5 when using thread pools. The interface has a single method executeRunnable task that accepts a task for execution based on the semantics and configuration of the thread pool. The TaskExecutor was originally created to give other Spring components an abstraction for thread pooling where needed. Components such as the ApplicationEventMulticaster , JMS’s AbstractMessageListenerContainer , and Quartz integration all use the TaskExecutor abstraction to pool threads. However, if your beans need thread pooling behavior, it is possible to use this abstraction for your own needs. TaskExecutor types There are a number of pre-built implementations of TaskExecutor included with the Spring distribution. In all likelihood, you shouldn’t ever need to implement your own. • SimpleAsyncTaskExecutor This implementation does not reuse any threads, rather it starts up a new thread for each invocation. However, it does support a concurrency limit which will block any invocations that are over the limit until a slot has been freed up. If you are looking for true pooling, see the discussions of SimpleThreadPoolTaskExecutor and ThreadPoolTaskExecutor below. • SyncTaskExecutor This implementation doesn’t execute invocations asynchronously. Instead, each invocation takes place in the calling thread. It is primarily used in situations where multi-threading isn’t necessary such as simple test cases. • ConcurrentTaskExecutor This implementation is an adapter for a java.util.concurrent.Executor object. There is an alternative, 4.3.9.RELEASE Spring Framework 758 ThreadPoolTaskExecutor , that exposes the Executor configuration parameters as bean properties. It is rare to need to use the ConcurrentTaskExecutor , but if the ThreadPoolTaskExecutor isn’t flexible enough for your needs, the ConcurrentTaskExecutor is an alternative. • SimpleThreadPoolTaskExecutor This implementation is actually a subclass of Quartz’s SimpleThreadPool which listens to Spring’s lifecycle callbacks. This is typically used when you have a thread pool that may need to be shared by both Quartz and non-Quartz components. • ThreadPoolTaskExecutor This implementation is the most commonly used one. It exposes bean properties for configuring a java.util.concurrent.ThreadPoolExecutor and wraps it in a TaskExecutor . If you need to adapt to a different kind of java.util.concurrent.Executor , it is recommended that you use a ConcurrentTaskExecutor instead. • WorkManagerTaskExecutor CommonJ is a set of specifications jointly developed between BEA and IBM. These specifications are not Java EE standards, but are standard across BEA’s and IBM’s Application Server implementations. This implementation uses the CommonJ WorkManager as its backing implementation and is the central convenience class for setting up a CommonJ WorkManager reference in a Spring context. Similar to the SimpleThreadPoolTaskExecutor , this class implements the WorkManager interface and therefore can be used directly as a WorkManager as well. Using a TaskExecutor Spring’s TaskExecutor implementations are used as simple JavaBeans. In the example below, we define a bean that uses the ThreadPoolTaskExecutor to asynchronously print out a set of messages. 4.3.9.RELEASE Spring Framework 759 import org.springframework.core.task.TaskExecutor; public class TaskExecutorExample { private class MessagePrinterTask implements Runnable { private String message; public MessagePrinterTaskString message { this .message = message; } public void run { System.out.printlnmessage; } } private TaskExecutor taskExecutor; public TaskExecutorExampleTaskExecutor taskExecutor { this .taskExecutor = taskExecutor; } public void printMessages { for int i = 0; i 25; i++ { taskExecutor.execute new MessagePrinterTask Message + i; } } } As you can see, rather than retrieving a thread from the pool and executing yourself, you add your Runnable to the queue and the TaskExecutor uses its internal rules to decide when the task gets executed. To configure the rules that the TaskExecutor will use, simple bean properties have been exposed. bean id = taskExecutor class = org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor property name = corePoolSize value = 5 property name = maxPoolSize value = 10 property name = queueCapacity value = 25 bean bean id = taskExecutorExample class = TaskExecutorExample constructor-arg ref = taskExecutor bean

34.3 The Spring TaskScheduler abstraction