Task Execution and Scheduling in Spring

Spring 2.0 introduced abstractions for asynchronous execution and scheduling of tasks. The key interfaces for scheduling and task execution are as listed as TaskExecutor, TaskScheduler, Trigger, TriggerContext and ScheduledFuture. Let take a look at each of these interfaces. This article explores spring’s scheduler related APIs in detail. You can read the official explanation for this API’s here.

follow us on @twitter and @facebook

TaskExecutor

TaskExecutor was introduced as an abstraction for dealing with executors. Executors are the Java 5 name for the concept of thread pools. The primary aim of TaskExecutor is to abstract away the need for Java 5 when using thread pools. The interface has only a single method as shown below:

public interface TaskExecutor extends java.util.concurrent.Executor {
void execute(Runnable task);
}

TaskExecutor Implementation Classes

  • SimpleAsyncTaskExecutor: Does not reuse threads. It starts a new thread and is asynchronus.
  • SyncTaskExecutor: No thread reuse and is synchonous. Instead, each invocation takes place in the calling thread.
  • ConcurrentTaskExecutor: Exposes the Java 5 java.util.concurrent.Executor.
  • SimpleThreadPoolTaskExecutor: It is a subclass of Quartz’s SimpleThreadPool which listens to Spring’s lifecycle callbacks.
  • ThreadPoolTaskExecutor: It exposes bean properties for configuring a ThreadPoolExecutor configuration and and wraps it in a TaskExecutor.
  • TimerTaskExecutor: This implementation uses a single TimerTask as its backing implementation. It’s different from the SyncTaskExecutor in that the method invocations are executed in a separate thread, although they are synchronous in that thread.
  • WorkManagerTaskExecutor: This implementation uses the CommonJ WorkManager as its backing implementation

TaskScheduler

This interface has a variety of methods for scheduling tasks to run at some point in the future, as seen below:

public interface TaskScheduler {
ScheduledFuture schedule(Runnable task, Trigger trigger);

    ScheduledFuture schedule(Runnable task, Date startTime);

    ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);

    ScheduledFuture scheduleAtFixedRate(Runnable task, long period);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
}

FixedRate – period will be measured from the start time
FixedDelay – period will be measured from the completion time

TaskScheduler Implementation Classes

  • TimerManagerTaskScheduler: Delegates to a CommonJ TimerManager instance, typically configured with a JNDI-lookup.
  • ThreadPoolTaskScheduler: Used whenever external thread management is not a requirement. Internally, it delegates to a ScheduledExecutorService instance.

Trigger

Using Trigger the execution times may be determined based on past execution outcomes or even arbitrary conditions. The Trigger interface is as follows:

public interface Trigger {
Date nextExecutionTime(TriggerContext triggerContext);
}

TriggerContext is an interface and encapsulates all of the relevant data.

Trigger Implementation Classes

  • CronTrigger: It enables the scheduling of tasks based on cron expressions.
  • PeriodicTrigger: It accepts a fixed period, an optional initial delay value, and a boolean to indicate whether the period should be interpreted as a fixed-rate or a fixed-delay.

Bootstrapping the scheduler

Since Spring 3.0, XML namespace for configuring TaskExecutor and TaskScheduler instances is available. It also provides a convenient way to configure tasks to be scheduled with a trigger. Add the following schema to the spring configuration file(xml file):


http://www.springframework.org/schema/task


http://www.springframework.org/schema/task/spring-task-3.0.xsd

Task Namespace
Add the following configuration :

<task:executor id="executor" pool-size="8-25" queue-capacity="100" />
<task:scheduler id="scheduler" pool-size="10" />
  • task:executor – Create instance of ThreadPoolTaskExecutor
  • task:scheduler – Create instance of ThreadPoolTaskScheduler
  • pool-size – If the value is not provided, then the default thread pool will only have a single thread.
  • queue-capacity – Number of tasks held back. Default value is Unbound
  • rejection-policy – This another attribute not mentione the above example. Used for to throw exception when a task is rejected. Its default value is AbortPolicy. Other possbile values are – DiscardPolicy , DiscardOldestPolicy , and CallerRunsPolicy.

Scheduling the Tasks

Tasks can be scheduled in the following three ways:

  1. Annotation Driven
  2. XML Driven
  3. Programmatically

1. Annotation Driven

The @Scheduled annotation can be added to a method along with trigger metadata for task scheduling. The @Async annotation can be provided on a method so that invocation of that method will occur asynchronously.

Add following to your spring configuration file:

<context:component-scan annotation-config="true" base-package="com.javabeat"/>
<task:annotation-driven executor="executor" scheduler="scheduler" />

The following example will only execute on weekdays.:

@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomeTask(){
 // some task that should execute on weekdays only
}

Scheduled methods must have void returns and must not expect any arguments.

Syntax for @Async annotation is:

@Async
void doSomething() {
    // this will be executed asynchronously
}

2. XML Driven

Add the following configuration to the spring configuration file :

<task:scheduled-tasks scheduler="sampleScheduler">
   <task:scheduled ref="someObject"
      method="someMethod" fixed-delay="5000"/>
</task:scheduled-tasks>

3. Programmatically

Go for programmatic way when your application desire more control on scheduling. For example :


ThreadPoolTaskScheduler scheduler = (ThreadPoolTaskScheduler) appContext.getBean("scheduler");
CronTrigger trigger = new CronTrigger("*/5 * * * * MON-FRI");

ScheduledFuture<Object> scedulefuture= scheduler.schedule(taskObject, trigger );

In the above example instead of schedule() method, you can use scheduleAtFixedRate(.. , ..) or scheduleWithFixedDelay(.. , ..).

Summary

In this post we saw the basics of task execution and scheduling in Spring. We studied the interfaces TaskExecutor, TaskScheduler, and Trigger and their implementation classes. We also saw methods of scheduling the tasks, annotation driven, XML driven and programmatically. In the next article I shall demonstrate this with an example. If you are interested in receiving the future articles, please subscribe here. follow us on @twitter and @facebook.

Comments

comments

About Manisha Patil

Manisha S Patil, currently residing at Pune India. She is currently working as freelance writer for websites. She had earlier worked at Caritor Bangalore, TCS Bangalore and Sungard Pune. She has 5 years of experience in Java/J2EE technologies.

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better