Java定时任务总结
一.从技术上分类大概分为以下三种方式:
1.Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务;
说明:
java.util.Timer定时器,实际上是个线程,定时执行TimerTask类
一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerTask一般是以匿名类的方式创建。
2.Java可以实现Runnable接口,这里不讲解,以后陆续补充;
3.Spring3.0以后自带的task,可以看做一个轻量级的Quartz,它的实现方式如下:
(1).Spring3.0 自带的作业调度(quartz)的两种业务处理方式
a.org.springframework.scheduling.quartz.JobDetailFactoryBean
b.org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
说明:Spring通过JobDetailBean/JobDetailFactoryBean,MethodInvokingJobDetailBean/MethodInvokingJobDetailFactoryBean实现Job的定义。
后者更加实用,只需指定要运行的类,和该类中要运行的方法即可,Spring将自动生成符合Quartz要求的JobDetail
(2).Spring3.0 自带的作业调度(quartz)的两种触发方式:
a. org.springframework.scheduling.quartz.SimpleTriggerBean 触发器 每隔多长时间运行一次 比如:每隔10分钟运行一次
b. org.springframework.scheduling.quartz.CronTriggerBean 调度器 每到指定时间则触发一次 比如:每天12:00运行一次
(3).配置调度任务,开启调度
org.springframework.scheduling.quartz.SchedulerFactoryBean
二.具体操作实现:
1.java.util.Timer :
一些基本方法的说明:
Timer timer = new Timer(true);
// true 说明这个timer以daemon方式运行(优先级低,
// 程序结束timer也自动结束),注意,javax.swing
// 包中也有一个Timer类,如果import中用到swing包,
// 要注意名字的冲突。
TimerTask task = new TimerTask() {
public void run() {
// 每次需要执行的代码放到这里面。
}
};
// 以下是几种调度task的方法:
//timer.schedule(task, time);
// time为Date类型:在指定时间频度执行一次。
//timer.schedule(task, firstTime, period);
// firstTime为Date类型,period为long
// 从firstTime时刻开始,每隔period毫秒执行一次。
//timer.schedule(task, delay);
// delay 为long类型:从现在起过delay毫秒执行一次
//timer.schedule(task, delay, period);
// delay为long,period为long:从现在起过delay毫秒以后,每隔period
// 毫秒执行一次。
package com.TimerWay.Timer; import java.util.TimerTask; public class TimerTaskJunit extends TimerTask { @Override public void run() { System.out.println("TimerTask1========="); } }
package com.TimerWay.Timer; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class Test { /** * 从现在起过1000毫秒以后,每隔2000毫秒,执行一次TimerTaskJunit的Run方法 */ public void test1(){ Timer timer = new Timer(); timer.schedule(new TimerTaskJunit(), 1000, 2000); } /** * 每天中午11:00:00 执行定时任务,如果当前时间超过了11点,就明天执行11点执行任务 */ public void test2(){ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); long period = 1000 * 60 * 24;//间隔执行时间 24分钟 Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Date now = new Date(); System.out.println(sdf.format(now)+"\t helloworld"); } },DateUtil.timeInMillis(), period); } public static void main(String[] args) { Test t = new Test(); t.test1(); //t.test2(); } }
2.Spring3.0 自带的Quartz
a.org.springframework.scheduling.quartz.JobDetailFactoryBean
<bean name="productDetail" class="com.TimerWay.quartz2.ProductDetail"/> <bean name="runJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.TimerWay.quartz2.RunJob" /> <!-- 属性注入 任务执行时 ,将属性注入到 jobClass对应Value类的属性 --> <property name="jobDataAsMap"> <map> <entry key="productDetail" value-ref="productDetail" /> </map> </property> </bean> <!-- Simple Trigger, run every 5 seconds first trigger --> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <!-- 任务 --> <property name="jobDetail" ref="runJob" /> <!-- 频度 每10分钟做一次任务 --> <property name="repeatInterval" value="600000" /> <!-- 待延迟之后,开始工作 --> <property name="startDelay" value="1000" /> </bean> <!-- 配置调度,启动调度任务 --> <bean id="schdulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobDetails"> <list> <ref bean="runMeJob" /> </list> </property> <property name="triggers"> <list> <ref bean="simpleTrigger" /> </list> </property> <!-- <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> --> </bean>
package com.TimerWay.quartz2; import org.apache.log4j.Logger; /** * 更新商城发货单的状态 * @author daizhao * */ public class ProductDetail { private final static Logger log = Logger.getLogger(ProductDetail.class); public void product(){ log.info("生产。。。。"); } }
说明:在这里我用的触发器是org.springframework.scheduling.quartz.SimpleTriggerFactoryBean,也可用
org.springframework.scheduling.quartz.CronTriggerFactoryBean,下面的例子,采用。
b.org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
<bean name="productDetail" class="com.TimerWay.quartz2.ProductDetail"/> <!-- 会自动的生成JobDetailFactoryBean --> <bean id="runMeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactor yBean"> <!-- 要执行业务的Bean --> <property name="targetObject" ref="productDetail" /> <!-- 执行业务的方法 --> <property name="targetMethod" value="product" /> </bean> <!--Cron Trigger, run every 5 seconds second trigger 类似Unix中的Crontab的脚步机制--> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!-- 任务 --> <property name="jobDetail" ref="runJob" /> <!-- 频度 --> <property name="cronExpression" value="0/5 * * * * ?" /> </bean> <!-- 配置调度,启动调度任务 --> <bean id="schdulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobDetails"> <list> <ref bean="runMeJob" /> </list> </property> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean>
说明:我解释一些,为什么我用这个JobDetailBean/JobDetailFactoryBean,MethodInvokingJobDetailBean/MethodInvokingJobDetailFactoryBean实现Job的定义,因为,有的时候,开发时,会遇到Spring自带的Quartz和Quartz包冲突的问题,异常如下:
所以,解决方式如下:
我后续,还会补充,Spring的注解定时任务和JavaRunnable定时任务,今天先到这里