Java ProgrammingLearn How to Schedule Tasks Using Spring

Learn How to Schedule Tasks Using Spring

Schedule Tasks

Task scheduling and asynchronous execution is an important feature of any framework or programming languages. Java has multiple implementation of thread pools, concurrent processing and execution. Spring framework is one of the most popular open source framework in the world of Java based enterprise/stand-alone application development. So, it has its own abstraction for concurrent task scheduling and execution.

In this article, we will explore how the execution and scheduling works in Spring framework. We will also check some code snippets to understand implementation in a better way.

What is TaskExecutor and TaskScheduler?
In this section, we will check the TaskExecutor and TaskScheduler one by one

TaskExecutor: –
Spring 2.0 has a new abstraction called TaskExecutor, it deals with executors. In Java 5, executors are basically thread pools. Spring’s abstraction layer simplified the use of executors. The TaskExecutor interface of Spring is identical to Java’s Executor interface. It is introduced to provide the facility of thread pools to different Spring components. Spring provides different implementations of TaskExecutor, like SimpleAsyncTaskExecutor, ConcurrentTaskExecutor, ThreadPoolTaskExecutor etc.

Let us check one simple implementation of TaskExecutor.

Listing 1: – Sample TaskExecutor implementation

package com.eduonix.taskexecutor;
import org.springframework.core.task.TaskExecutor;
public class SampleTaskExecutor {	
	//Creating Thread class
	private class PrintMessageTsk implements Runnable {
	    private String msg;
	    public PrintMessageTsk(String msg) {
	      this.msg = msg;
	    }
	    public void run() {
	      System.out.println(msg);
	    }
	  }
	//Creating executor instance  
	private TaskExecutor tskExeqtor;
	public SampleTaskExecutor(TaskExecutor tskExeqtor) {
	    this.tskExeqtor = tskExeqtor;
	  }
	//Start executing threads
	public void printMsg() {
	    for(int i = 0; i < 20; i++) {
	      tskExeqtor.execute(new PrintMessageTsk("Message is: " + i));
	    }
	  }
}

In the following listing, we have configured a sample rule for the TaskExecutor. In this XML configuration, the core pool size is 6, maximum pool is 12 and the queue capacity is 30.

Listing 2: – Sample rule configuration

<bean id="smpltaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="6" />
  <property name="maxPoolSize" value="12" />
  <property name="queueCapacity" value="30" />
</bean>
<bean id="sampleTaskExecutor" class="SampleTaskExecutor">
  <constructor-arg ref="smpltaskExecutor" />
</bean>

If we check the sample code carefully (Listing 1), we can understand that no thread is retrieved and executed from the pool manually. We are just adding the Runnable implementation in the queue, and the rest is taken care of by the internal rules of TaskExecutor. And, it manages all the threads internally. It is a great relief to the developers’ community, as they don’t need to worry about the thread management.

TaskScheduler: –
Spring 3.0 introduces TaskScheduler. It helps to schedule tasks at any point of time in the future. It also comes with features to check the status of tasks and even their cancellation. To implement TaskScheduler, we need to prepare a runnable task and select proper method to schedule it.

In the following listing, we can have a look at different methods offered by the interface.

Listing 3: – Showing methods in TaskScheduler interface

public interface TaskScheduler {
    ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
    ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
    ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
    ScheduledFuture schedule(Runnable task, Trigger trigger);
    ScheduledFuture schedule(Runnable task, Date startTime);
    ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
}

In the above methods, the simplest one is the one which contains the Runnable task and date. And, the method having Trigger is the complex one.

Let’s have a look at Triggers as it has some complex implementation.

The Trigger interface is a part of Spring 3.0. The basic idea is to control the execution time based on the past execution outcomes. The outcome of the previous execution is wrapped in a TriggerContext. TriggerContext is another important interface, which encapsulates all the relevant information.

Following code snippets shows the basic structure of Trigger and TriggerContext interface.

Listing 4: – Showing methods in Trigger interface

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

Listing 5: – Showing methods in TriggerContext interface

public interface TriggerContext {
    Date lastScheduledExecutionTime();
    Date lastActualExecutionTime();
    Date lastCompletionTime();
}

What are the ways to Schedule Tasks?
In this section, we will check how different type of scheduled tasks can be implemented. We will focus on the coding side of the scheduler tasks.

We will concentrate on the following types.
• Schedule with Fixed Delay
• Schedule with Fixed Rate
• Schedule with Cron Trigger

Before jumping into the above scheduling types, we will have a brief look at ThreadPoolTaskScheduler. ThreadPoolTaskScheduler is a simpler way to manage and schedule tasks. It implements Spring’s TaskExecutor interface. Here, the single instance is used for asynchronous execution and scheduled tasks.

Schedule with fixed delay
There are two different ways to schedule Runnable task with fixed delay.

• Fixed delay after the completion of last execution.

tskScheduler.scheduleWithFixedDelay(
  	new RunnableTask("Fixed delay with 2 second"), 2000);

• Fixed delay after a specific date.

tskScheduler.scheduleWithFixedDelay(
  new RunnableTask("Fixed delay of 2 seconds after current date"),
  new Date(),
  2000);

Schedule with fixed rate: –
Even here, there are two different ways to schedule tasks with fixed rate.

• Scheduling with a fixed rate

tskScheduler.scheduleAtFixedRate(
  new RunnableTask("Scheduled with fixed rate of 3 seconds") , 3000);

• Scheduling with a fixed rate after a specific date.

tskScheduler.scheduleAtFixedRate(new RunnableTask(
  "Scheduled with fixed rate of 4 seconds"), new Date(), 4000);

Schedule with cron trigger
CronTrigger is a bit complex in nature. It helps to schedule a task based on a cron expression.

CronTrigger crnTrigger 
  = new CronTrigger("0 0 6 * * ?");
  
tskScheduler.schedule(new RunnableTask("Cron Trigger"), crnTrigger);

The above job will run 6AM every morning as per the cron expression.

Conclusion: –
This article is all about the concepts behind Spring’s TaskExecutor and TaskScheduler. It describes all the important points and their implementation details. This brief overview will give you an idea and help you implement it in your project.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -