最近项目中使用到了定时器的功能,在每天凌晨,如果内存中存有数据,将会把内存中的数据刷入数据库中。
从任务调度的触发时机来分,主要是针对作业使用的触发器,有一下两种:
(1)每隔指定时间触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean
(2)每到指定时间触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean
1.java中的定时器 Timer
使用java中的java.util.Timer工具类,这个类允许调度一个java.util.TimeTask任务。
(1)每隔指定时间触发一次
<pre name="code" class="java">java.util.Timer timer;
timer = new Timer(false);//如果为true,这个线程是一个守护线程,如果调用几个timer.schedule()方法,则只有第一个被执行,后面几个会被屏蔽,如果把这个参数设置为false,后面的调用才能生效。
java.util.TimerTask task = new java.util.TimerTask()
{
public void run()
{
//flush();要操作的方法
}
};
java.util.Date time = new java.util.Date();
long delay = 2000;
long period = 5000;
//启动定时任务,立即执行一次并退出
timer.schedule(task,time);
//启动定时任务,立即执行一次,然后每隔两秒执行一次
timer.schedule(task,time,delay);
//启动定时任务,从现在起过两秒执行一次然后退出
timer.schedule(task,delay);
//启动定时任务,从现在起过两秒以后,每隔五秒执行一次
timer.schedule(task,delay,period);
第一个参数是要操作的方法,第二个参数是要设定延迟的时间,第三个参数是周期的设定,每隔多长时间执行该操作。
使用这几行代码以后,Timer本身会每隔5分钟调用一次flush方法,不需要自己启动线程。Timer本身也是多线程同步的,多个线程可以共用一个Timer,不需要外部同步代码。
使用这种方式可以使程序按照某一个频度执行,但不能再指定的时间运行。
(2)每到指定时间触发一次
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Timerc {
static int count = 0;
public static void showTimer() {
TimerTask task = new TimerTask() {
@Override
public void run() {
++count;
System.out.println("时间=" + new Date() + " 执行了" + count + "次"); // 1次
}
};
//设置执行时间
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);//每天
//定制每天的17:00:00执行,
calendar.set(year, month, day, 19, 00, 00);
Date date = calendar.getTime();
Timer timer = new Timer();
System.out.println(date);
int period = 1 * 3600 * 1000;
//每天的date时刻执行task,每隔一小时重复执行
timer.schedule(task, date, period);
//每天的date时刻执行task, 仅执行一次
//timer.schedule(task, date);
}
public static void main(String[] args) {
showTimer();
}
}
2. 使用Quartz
这是一个功能强大的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行。
用法:
(1)作业类继承自特定的基类
org.springframework.scheduling.quartz.QuartzJobBean
第一步:定义作业类
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class Job1 extends QuartzJobBean {
private int timeout;
private static int i = 0;
//调度工厂实例化后,经过timeout时间开始执行调度
public void setTimeout(int timeout) {
this.timeout = timeout;
}
/**
* 要调度的具体任务
*/
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
System.out.println("定时任务执行中…");
}
}
第二步:spring配置文件中配置作业类JobDetailBean
<bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.gy.Job1" />
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="0" />
</map>
</property>
</bean>
说明:org.springframework.scheduling.quartz.JobDetailBean有两个属性,jobClass属性即我们在java代码中定义的任务类,jobDataAsMap属性即该任务类中需要注入的属性值。
第三步:配置作业调度的触发方式(触发器)
Quartz的作业触发器有两种,分别是
org.springframework.scheduling.quartz.SimpleTriggerBean
org.springframework.scheduling.quartz.CronTriggerBean
第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。
配置方式如下:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="job1" />
<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 -->
</bean>
第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次。
配置方式如下:
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="job1" />
<!—每天12:00运行一次 -->
<property name="cronExpression" value="0 0 12 * * ?" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
说明:该参数指定的就是之前配置的触发器的名字。
第五步:启动应用,即将工程部署到tomcat或其他容器。
(2)作业类不继承特定基类
3. Spring3.0以后自带的Task
可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单的多,除Spring相关的包外不需要额外的包,并且支持注解和配置文件两种形式。
参考:
http://www.cnblogs.com/wyqtomorrow/archive/2007/04/28/730978.html
http://gong1208.iteye.com/blog/1773177 2.2和3的两种方式详细介绍。
http://m.oschina.net/blog/148424 spring注入方式quartz定时调用处理的代码实现
http://blog.sina.com.cn/s/blog_6d0730c70100y9gf.html