java.util下的Timer,TimerTask和quartz的比较
2006-11-13 21:43
447 查看
Java中已经有一个timer类可以用来进行执行计划,定时任务。我们所要做的只是继承java.util.TimerTask类。如下所示:Quartz。Quartz定义了两种基本接口
Cron的小小说明
packagecom.yourcompany.scheduling;
importjava.util.Calendar;
importjava.util.Date;
importjava.util.Timer;
importjava.util.TimerTask;
publicclassReportGeneratorextendsTimerTask{
publicvoidrun(){
System.out.println("Generatingreport");
//TODOgeneratereport
}
}
classMainApplication{
publicstaticvoidmain(String[]args){
TimertimernewTimer();
Calendardate=Calendar.getInstance();
date.set(
Calendar.DAY_OF_WEEK,
Calendar.SUNDAY
);
date.set(Calendar.HOUR,0);
date.set(Calendar.MINUTE,0);
date.set(Calendar.SECOND,0);
date.set(Calendar.MILLISECOND,0);
//ScheduletoruneverySundayinmidnight
timer.schedule(
newReportGenerator(),//TimerTask
date.getTime(),//Timer
1000*60*60*24*7//delay
);
}
}这里有几个问题,我们的类继承了TimerTask,而timerTask也是实现了java.lang.Runnable接口。我们所要做的只是在我们自己的类里重置run()方法。所以我们的TimerTask类其实是一种线程,但线程的调度往往不是按照我们希望来实现的,因为一些垃圾收集等原因,我们计划的时间点,却没有执行必要的任务。这样会产生一些问题。虽然,Timer类也提供了
scheduleAtFixedRate()方法用来在垃圾收集后能够快速的追上任务进度,但这个不一定是我们所需要的。特别是在一些J2EE服务器上Timer是无法控制的,因为它不在容器的权责范围内。另外的,这个任务调度也缺乏一些企业级所需要的特殊日期定制的功能,以及修改,查找任务的功能。这里我们要介绍的是一个开源项目:
Job和
Trigger。看名字也就知道,我们的任务必须实现Job,我们的时间触发器定义在Trigger内。看一个例子也许能更快的了解他的使用方法:
packagecom.yourcompany.scheduling;
importorg.quartz.*;
publicclassQuartzReportimplementsJob{
publicvoidexecute(JobExecutionContextcntxt)//
必须实现的方法
throwsJobExecutionException{
System.out.println(
"Generatingreport-"+
cntxt.getJobDetail().getJobDataMap().get("type")
);
//TODOGeneratereport
}
publicstaticvoidmain(String[]args){
try{
SchedulerFactoryschedFact
neworg.quartz.impl.StdSchedulerFactory();
Schedulersched=schedFact.getScheduler();
sched.start();
JobDetailjobDetail=
newJobDetail(
"IncomeReport",//
任务名
"ReportGeneration",//
任务组
QuartzReport.class//
任务执行的类
);
jobDetail.getJobDataMap().put(
"type",
"FULL"
)
;
CronTriggertriggernewCronTrigger(
"IncomeReport",//
触发器名
"ReportGeneration"//
触发器组
);
trigger.setCronExpression(//
触发器时间设定
"0012?*SUN"
);
sched.scheduleJob(jobDetail,trigger);//
执行任务
}catch(Exceptione){
e.printStackTrace();
}
}
}这里面我们可以看到,当我们定义了任务执行
QuartzReport类后,需要定一个
Scheduler类用来执行计划任务。一个
JobDetail类来描述这个任务的信息,包括任务信息,任务所在组,任务执行的类。然后还要定义一个触发器,类似的也包括触发器名,触发器所在组,触发器触发时间设定。最后是调度器
Scheduler类执行计划任务。基本上一个计划任务执行的流程就完成了。当然,我们还看到了上面红色代表的内容,这些内容主要是提供在job方法执行的时候所需要的参数的提供。这里使用了
JobDataMap类,它其实就是实现了map的特殊应用的一个类,使用方法与Map很相似。我们可以用put()输入参数。在Job类中使用
cntxt.getJobDetail().getJobDataMap().get("type")方法获取输入的参数的值。这里的cntxt是
JobExecutionContext。就是包含任务执行上下文的一个信息类。这样我们的一个基本的任务执行就可以搞定了。触发器有两类:
SimpleTriggerand
CronTrigger.。
SimpleTrigger主要提供了跟java.util.Timer类相似的功能.。你可以在里面定义任务的起始时间,终止时间,任务的执行次数,任务执行的中间间隔。而
CronTrigger类主要提供了更高级的任务调度时间设置,例如每个星期天的早上7点。
CronTrigger的时间设置说明在最后来介绍。下面我们介绍一下在J2EE环境下如何来使用Quartz。首先,我们要配置web.xml,添加一下内容,主要是Quartz的初始化,<servlet><servlet-name>QuartzInitializer</servlet-name><display-name>QuartzInitializerServlet</display-name><servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class><load-on-startup>1</load-on-startup></servlet>然后还要有一个Quartz的配置文件quartz.properties放置在WEB-INF/classes目录下面。StdScheduleFactory()会读取它。配置如下
#
#ConfigureMainSchedulerProperties
#
org.quartz.scheduler.instanceName=TestScheduler
org.quartz.scheduler.instanceId=one
#
#ConfigureThreadPool
#
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=4
#
#ConfigureJobStore
#
org.quartz.jobStore.misfireThreshold=5000
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore这里我们使用的
RAMJobStore存储方式,这样如果我们的web服务器重启的话,我们所有未执行的任务信息都回丢失。当然,我们也有另外的选择,我们可以把这样的信息存储在数据库内,就是使用
JDBCJobStoreTX
#
#ConfigureThreadPool
#
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=QRTZ_
#
#ConfigureDatasources
#
org.quartz.dataSource.myDS.driver=org.postgresql.Driver
org.quartz.dataSource.myDS.URL=jdbc:postgresql:dev
org.quartz.dataSource.myDS.user=dejanb
org.quartz.dataSource.myDS.password=
org.quartz.dataSource.myDS.maxConnections5附:cronExpression配置说明
字段 | 允许值 | 允许的特殊字符 | ||
秒 | 0-59 | ,-*/ | ||
分 | 0-59 | ,-*/ | ||
小时 | 0-23 | ,-*/ | ||
日期 | 1-31 | ,-*?/LWC | ||
月份 | 1-12或者JAN-DEC | ,-*/ | ||
星期 | 1-7或者SUN-SAT | ,-*?/LC# | ||
年(可选) | 留空,1970-2099 | ,-*/ |
表示方式 | 意义 |
"0012**?" | Fireat12pm(noon)everyday |
"01510?**" | Fireat10:15ameveryday |
"01510**?" | Fireat10:15ameveryday |
"01510**?*" | Fireat10:15ameveryday |
"01510**?2005" | Fireat10:15ameverydayduringtheyear2005 |
"0*14**?" | Fireeveryminutestartingat2pmandendingat2:59pm,everyday |
"00/514**?" | Fireevery5minutesstartingat2pmandendingat2:55pm,everyday |
"00/514,18**?" | Fireevery5minutesstartingat2pmandendingat2:55pm,ANDfireevery5minutesstartingat6pmandendingat6:55pm,everyday |
"00-514**?" | Fireeveryminutestartingat2pmandendingat2:05pm,everyday |
"010,4414?3WED" | Fireat2:10pmandat2:44pmeveryWednesdayinthemonthofMarch. |
"01510?*MON-FRI" | Fireat10:15ameveryMonday,Tuesday,Wednesday,ThursdayandFriday |
"0151015*?" | Fireat10:15amonthe15thdayofeverymonth |
"01510L*?" | Fireat10:15amonthelastdayofeverymonth |
"01510?*6L" | Fireat10:15amonthelastFridayofeverymonth |
"01510?*6L" | Fireat10:15amonthelastFridayofeverymonth |
"01510?*6L2002-2005" | Fireat10:15amoneverylastfridayofeverymonthduringtheyears2002,2003,2004and2005 |
"01510?*6#3" | Fireat10:15amonthethirdFridayofeverymonth |
相关文章推荐
- java.util下的Timer,TimerTask和quartz的比较
- java.util下的Timer,TimerTask和quartz的比较
- java.util下的Timer,TimerTask和quartz的比较
- java.util下的Timer,TimerTask和quartz的比较
- 几种任务调度的 Java 实现方法与比较Timer,ScheduledExecutor,Quartz,JCronTab
- 几种任务调度的 Java 实现方法与比较Timer,ScheduledExecutor,Quartz,JCronTab
- java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享
- java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享
- 定时任务 java.util.Timer和TimerTask
- Java中Timer和TimerTask的使用
- Java中的Timer和TimerTask的使用
- Java线程(四):Timer和TimerTask
- java.util.Timer 定时问题
- java.util.concurrent.locks.LockSupport (讲得比较细)
- Java中的Timer和TimerTask的用法
- mybatis异常invalid comparison: java.util.Date and java.lang.String(date和string无法比较)
- Java中使用Timer和TimerTask实现多线程
- Java中的Timer和TimerTask在Android中的用法
- 【Java多线程】-Timer,TimerTask,ScheduledExecutorService
- 使用Java中的Timer和TimerTask