下面介绍几种常用的定时器及其实现方法:
第一种:Timer和TimerTask
Timer实际上是个线程,它可以定时调度一个TimerTask对象。一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内。
Timer及其方法:
- java.util.Timer timer = new java.util.Timer(true);
-
- TimerTask task = new TimerTask() {
- public void run() {
-
- }
- };
-
-
- timer.schedule(task, time);
- timer.schedule(task, firstTime, period);
- timer.schedule(task, delay)
- timer.schedule(task, delay, period)
-
-
- timer.scheduleAtFixedRate(task, delay, period);
- timer.scheduleAtFixedRate(task, firstTime, period);
一个完整的例子:
- import java.util.Date;
- import java.util.TimerTask;
-
- public class MyTimerTask extends TimerTask {
- @Override
- public void run() {
- System.out.println("定时器开始执行任务……" + new Date());
- }
- }
- import java.util.Timer;
-
- public class MyTimer {
- public static void main(String[] args) {
- Timer timer = new Timer();
- int delay = 2*1000;
- int period = 3*1000;
- timer.scheduleAtFixedRate(new MyTimerTask(), delay, period);
- }
- }
第二种:使用Spring的任务调度类ScheduledExecutorTask
实现方法:
第一步:建立一个Java类,并实现Runnable接口:
- package com.xjj.anes.schedule;
-
- public class StartupTask implements Runnable{
- @Override
- public void run() {
-
- }
- }
第二步:Spring配置
- <bean id="startupTask" class="com.xjj.anes.schedule.StartupTask" />
- <bean id="startupScheduledTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
- <property name="delay" value="3000" />
- <property name="period" value="0" /> <!-- 0表示只执行一次,毫秒 -->
- <property name="runnable" ref="startupTask" />
- </bean>
-
- <bean id="timerFactory" class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
- <property name="scheduledExecutorTasks">
- <list>
- <ref bean="startupScheduledTask" />
- </list>
- </property>
- </bean>
或直接使用注解:
- <task:annotation-driven scheduler="myScheduler" />
- <task:scheduler id="myScheduler" pool-size="10" />
- @Scheduled(fixedDelay=5000)
- public void doSomething() {
- System.out.println("每5秒钟执行一次。");
- }
-
- @Scheduled(fixedRate=5000)
- public void doSomething() {
-
- }
-
- @Scheduled(initialDelay=1000, fixedRate=5000)
- public void doSomething() {
-
- }
-
- @Scheduled(cron="*/5 * * * * MON-FRI")
- public void doSomething() {
-
- }
或完全使用配置:
- <task:scheduled-tasks scheduler="myScheduler">
- <task:scheduled ref="beanA" method="methodA" fixed-delay="5000" initial-delay="1000"/>
- <task:scheduled ref="beanB" method="methodB" fixed-rate="5000"/>
- <task:scheduled ref="beanC" method="methodC" cron="*/5 * * * * MON-FRI"/>
- </task:scheduled-tasks>
-
- <task:scheduler id="myScheduler" pool-size="10"/>
第三种:Spring与Quartz整合实现定时任务调度
第一步:引入相关的依赖包
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>4.1.2.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>2.2.1</version>
- </dependency>
第二步:建立一个Java类,不需要继承如何类或实现任何接口
- public class MyTask{
- public void putDataToCache() {
- log.info("Alert! putDataToCache........" + new Date());
- }
- }
第三步:Spring配置
- <bean id="myTask" class="com.xjj.anes.schedule.MyTask" />
-
-
- <bean id="putDataToCacheTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
- <property name="jobDetail">
-
- <bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="concurrent" value="false"/>
- <property name="targetObject" ref="myTask"/>
- <property name="targetMethod" value="putDataToCache"/>
- </bean>
- </property>
- <property name="cronExpression" value="0 0 0/2 * * ?"/>
- </bean>
-
-
- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref bean="putDataToCacheTrigger" />
- </list>
- </property>
- <property name="startupDelay" value="6"/>
- </bean>
cronExpression表达式定义:
字段 | | 允许值 | | 允许的特殊字符 |
---|
秒 | | 0-59 | | , - * / |
分 | | 0-59 | | , - * / |
小时 | | 0-23 | | , - * / |
日期 | | 1-31 | | , - * ? / L W C |
月份 | | 1-12 或者 JAN-DEC | | , - * / |
星期 | | 1-7 或者 SUN-SAT | | , - * ? / L C # |
年(可选) | | 留空, 1970-2099 | | , - * / |
一些表达式的例子:
表达式 | | 意义 |
---|
"0 0 12 * * ?" | | 每天中午12点触发 |
"0 15 10 ? * *" | | 每天上午10:15触发 |
"0 15 10 * * ?" | | 每天上午10:15触发 |
"0 15 10 * * ? *" | | 每天上午10:15触发 |
"0 15 10 * * ? 2005" | | 2005年的每天上午10:15 触发 |
"0 * 14 * * ?" | | 在每天下午2点到下午2:59期间的每1分钟触发 |
"0 0/5 14 * * ?" | | 在每天下午2点到下午2:55期间的每5分钟触发 |
"0 0/5 14,18 * * ?" | | 在每天下午2点到2:55期间和下午6点到6:55期间的每 5分钟触发 |
"0 0-5 14 * * ?" | | 在每天下午2点到下午2:05期间的每1分钟触发 |
"0 10,44 14 ? 3 WED" | | 每年三月的星期三的下午2:10和2:44触发 |
"0 15 10 ? * MON-FRI" | | 周一至周五的上午10:15触发 |
"0 15 10 15 * ?" | | 每月15日上午10:15触发 |
"0 15 10 L * ?" | | 每月最后一日的上午10:15触发 |
"0 15 10 ? * 6L" | | 每月的最后一个星期五上午10:15触发 |
"0 15 10 ? * 6L 2002-2005" | | 2002年至2005年的每月的最后一个星期五上午 10:15触发 |
"0 15 10 ? * 6#3" | | 每月的第三个星期五上午10:15触发 |
0 6 * * *
每天早上6点
0 */2 * * *
每两个小时
0 23-7/2,8 * * *
晚上11点到早上8点之间每两个小时,早上八点
0 11 4 * 1-3
每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 4 1 1 *
1月1日早上4点
特殊字符 | | 意义 |
---|
* | | 表示所有值; |
? | | 表示未说明的值,即不关心它为何值;'?'也代表 '任何值', 但只用于“日期”和“星期几”,当其中一个设置了条件时,另外一个就要用'?' 来表示 '任何值'; |
- | | 表示一个指定的范围; |
, | | 表示附加一个可能值; |
/ | | 符号前表示开始时间,符号后表示每次递增的值; |
L("last") | | ("last") "L" 用在day-of-month字段意思是 "这个月最后一天";用在 day-of-week字段, 它简单意思是 "7" or "SAT"。如果在day-of-week字段里和数字联合使用,它的意思就是 "这个月的最后一个星期几" – 例如: "6L" means "这个月的最后一个星期五". 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会得到一些意想不到的结果。 |
W("weekday") | | 只能用在day-of-month字段。用来描叙最接近指定 天的工作日(周一到周五)。例如:在day-of-month字段用“15W”指“最接近这个月第15天的工作日”,即如果这个月第15天是周六,那么触 发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第16 天即周一触发;如果这个月第15天是周二,那么就在触发器这天触发。注意一点:这个用法只会在当前月计算值,不会越过当前月。“W”字符仅能在day- of-month指明一天,不能是一个范围或列表。也可以用“LW”来指定这个月的最后一个工作日。 |
# | | 只能用在day-of-week字段。用来指定这个月的第几 个周几。例:在day-of-week字段用"6#3"指这个月第3个周五(6指周五,3指第3个)。如果指定的日期不存在,触发器就不会触发。 |
C | | 指和calendar联系后计算过的值。例:在day- of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第 一天。 |
转自博客:http://blog.csdn.net/clementad/article/details/42042111