Using TimeTask is pretty old way, and is not recommended anymore. Use @Scheduled annotation for the latest and recommended approach.
Java Timer is a utility class that schedules tasks for one-time and repeated execution. Through timer tasks, the Spring Framework provides support for executing tasks that are scheduled to be executed periodically for multiple times or even a single time.
There are other ways to achieve scheduler functionality in Java, e.g., running a thread in an infinite loop, using the executor service, or using third-party APIs like Quartz. Timer just happens to be one of them.
Please note that
Timeris dependent on system clock so setting back system clock by n hours, would prevent the next execution of timer task also by n hours.
In Spring, there are two ways to use timer tasks:
- Configure
MethodInvokingTimerTaskFactoryBean - Extend
java.util.TimerTask
Let’s demo the usage of each one using examples.
1. Configure MethodInvokingTimerTaskFactoryBean
In this method, timer task bean and method to be executed inside it, is configured in org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean definition. This is a factory bean which exposes a TimerTask object which delegates job execution to a specified (static or non-static) method. This avoids the need to implement a one-line TimerTask that just invokes an existing business method.
A sample spring configuration will look like this:
<beans>
<bean id="demoTimerTask" class="com.howtodoinjava.task.DemoTimerTask"></bean>
<bean id="timerTaskFactoryBean"
class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="demoTimerTask"></property>
<property name="targetMethod" value="execute"></property>
</bean>
<bean id="scheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="timerTaskFactoryBean"></property>
<property name="period" value="5000"></property>
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="scheduledTimerTask"></ref>
</list>
</property>
</bean>
</beans>
Above timer task will get executed in every 5 seconds. Lets write out demo timer task and test it.
import java.util.Date;
/**
* No need to implement any interface
* */
public class DemoTimerTask {
//Define the method to be called as configured
public void execute()
{
System.out.println("Executed task on ::" + new Date());
}
}
Now, let us test the timer task.
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemoTimerTask {
public static void main(String[] args) {
new ClassPathXmlApplicationContext("application-config.xml");
}
}
Executed task on :: Mon Apr 22 09:53:39 IST 2017
Executed task on :: Mon Apr 22 09:53:44 IST 2017
2. Extend java.util.TimerTask
This way, we define our timer task by extending java.util.TimerTask and passing it to the spring configuration to execute it repeatedly.
Lets see how to do it:
<beans>
<bean id="demoTimerTask" class="com.howtodoinjava.task.DemoTimerTask2"></bean>
<bean id="scheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!-- run every 3 secs -->
<property name="period" value="3000"></property>
<property name="timerTask" ref="demoTimerTask"></property>
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="scheduledTimerTask"></ref>
</list>
</property>
</bean>
</beans>
The above task will be executed every 3 seconds. Let’s extend our timer task from the TimerTask provided by Java.
import java.util.Date;
import java.util.TimerTask;
public class DemoTimerTask2 extends TimerTask
{
public void run()
{
System.out.println("DemoTimerTask2 running at: " + new Date(this.scheduledExecutionTime()));
}
}
Let’s test the configuration:
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemoTimerTask2
{
public static void main(String[] args)
{
new ClassPathXmlApplicationContext("application-config2.xml");
}
}
DemoTimerTask2 running at: Mon Apr 22 10:01:33 IST 2013
DemoTimerTask2 running at: Mon Apr 22 10:01:36 IST 2013
DemoTimerTask2 running at: Mon Apr 22 10:01:39 IST 2013
Happy Learning !!
Hi, I Used fixed delay and run the web application, it’s working perfect on the JBOSS server, but recently we moved our web application from JBOSS to tomcat, this scheduler function is not working… is there any suggestion for this.
Anybody would like to suggest anything??
simple, straight forward tutorial that I can apply in my work, thanks for this
How can I change the “period” programmatically?
Try creating an instance of “ScheduledTimerTask” and set the period of your choice. Now try to add this in list of “scheduledTimerTasks”.
https://docs.spring.io/spring-framework/docs/2.0.x/javadoc-api/org/springframework/scheduling/timer/TimerFactoryBean.html
Use method: registerTasks(ScheduledTimerTask[] tasks, Timer timer)
Please let me know if you was able to do it.
yes , but both TimerTask and Spring’s built-in scheduler creates new Thread’s for scheduling and they have same functionality, in addition using spring’s built-in scheduler like Quartz, we can use flexible ‘cron’ expressions for running tasks.
Your comment inspired me dig more on other ways for task scheduling. I will cover more of them in future posts. But, for now I just posted my learning around @Scheduled annotation in below post:
https://howtodoinjava.com/spring-boot/enable-scheduling-scheduled-job-example/
Good , I’m happy for that :)
note that in Spring3, “ScheduledTimerTask” is deprecated. The better way to work with timers is like you describe in your other blog post….
I think using @Scheduled annotation is easiest way to execute timer tasks in spring 3.
Hamid, I doubt that @Scheduled is not used for timer tasks, though it serve the same purpose i.e. executing task periodically.
Above both techniques use java.util.TimerTask class internally. But in case of @Scheduled, Spring 3’s built-in scheduler just like quartz.
Please correct me if i am missing anything ??