spring学习系列 -- 定时器三 两种定时器的比较

来源:互联网 发布:数据平滑处理的方法 编辑:程序博客网 时间:2024/05/16 09:08

http://huangrongyou.iteye.com/blog/1762869

  前2篇文章介绍了spring的两种定时器:TimerTask 和 Quartz,本篇要在这两篇的基础上,讲讲两者的区别。

 

精确度和功能

   Quartz可以通过cron表达式精确到特定时间执行,而TimerTask不能。Quartz拥有TimerTask所有的功能,而TimerTask则没有。

 

任务类的数量

    TimerTask和Quartz每次执行任务时,每次调用的是不是都是同一个任务类对象,还是每次都不一样?现在做如下实验,每次执行任务时,将任务类对象本身打印出来。

 

Quartz任务类

public class MyJob extends QuartzJobBean {private String sTest;@Overrideprotected void executeInternal(JobExecutionContext job)throws JobExecutionException {// TODO Auto-generated method stubSystem.out.println("sTest = " + sTest);System.out.println("MyJob Run..." + this);}// set/get 略}

Quartz输出结果

</pre><pre name="code" class="java">sTest = 10MyJob Run...com.hry.spring.timertask.MyJob@1060478sTest = 10MyJob Run...com.hry.spring.timertask.MyJob@db4fa2sTest = 10MyJob Run...com.hry.spring.timertask.MyJob@491c4c

从输出结果可以看出,Quartz每次执行都创建一个新的任务类对象。

 

TimerTask任务类

public class EmailReportTask extends TimerTask{   // 每次执行过程中num的值都会发生变化,说明此事使用的是同一个类对象private int num = 0;    @Override       public void run() {       System.out.println("num = " + num++);    System.out.println(this);    }     }  
TimerTask任务类的输出结果

num = 0com.hry.spring.timertask.EmailReportTask@1581593PageReportTask Run...num = 1com.hry.spring.timertask.EmailReportTask@1581593PageReportTask Run...

 从输出结果可以看出,TimerTask每次执行时,都是使用同一个对象

 从以上的分析,可以得出结论:Quartz每次执行任务都创建一个新的任务类对象,而TimerTask则每次使用同一个任务类对象。

 

对异常的处理

一个循环执行的任务,如果某一次执行任务时,因为某些原因抛出异常,则定时器是否还会在下一个执行任务的时间点执行任务吗?下面通过模拟在任务类中抛出异常,来模拟这种情况,并测试两种定时器如何处理这种情况。

Quartz任务类

public class MyJob extends QuartzJobBean {private String sTest;@Overrideprotected void executeInternal(JobExecutionContext job)throws JobExecutionException {// TODO Auto-generated method stubSystem.out.println("sTest = " + sTest);System.out.println("MyJob Run..." + this);throw new RuntimeException("Test");}// set/get 方法略}

Quartz输出结果

sTest = 10MyJob Run...com.hry.spring.timertask.MyJob@16f25a72013-01-05 19:58:37,381 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-3] ERROR [org.quartz.core.JobRunShell] - Job DEFAULT.reportJob threw an unhandled Exception:   java.lang.RuntimeException: Testat com.hry.spring.timertask.MyJob.executeInternal(MyJob.java:24)at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)at org.quartz.core.JobRunShell.run(JobRunShell.java:223)at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)2013-01-05 19:58:37,396 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-3] ERROR [org.quartz.core.ErrorLogger] - Job (DEFAULT.reportJob threw an exception.  org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.RuntimeException: Test]at org.quartz.core.JobRunShell.run(JobRunShell.java:234)at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)Caused by: java.lang.RuntimeException: Testat com.hry.spring.timertask.MyJob.executeInternal(MyJob.java:24)at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)at org.quartz.core.JobRunShell.run(JobRunShell.java:223)... 1 moresTest = 10MyJob Run...com.hry.spring.timertask.MyJob@110c312013-01-05 19:58:39,381 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] ERROR [org.quartz.core.JobRunShell] - Job DEFAULT.reportJob threw an unhandled Exception:   java.lang.RuntimeException: Testat com.hry.spring.timertask.MyJob.executeInternal(MyJob.java:24)at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)at org.quartz.core.JobRunShell.run(JobRunShell.java:223)at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)2013-01-05 19:58:39,396 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] ERROR [org.quartz.core.ErrorLogger] - Job (DEFAULT.reportJob threw an exception.  org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.RuntimeException: Test]at org.quartz.core.JobRunShell.run(JobRunShell.java:234)at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)Caused by: java.lang.RuntimeException: Testat com.hry.spring.timertask.MyJob.executeInternal(MyJob.java:24)at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)at org.quartz.core.JobRunShell.run(JobRunShell.java:223)... 1 more

 以上结果中多次出现

sTest = 10  MyJob Run...com.hry.spring.timertask.MyJob@110c31 

可以看出,尽管每次执行任务时,任务类都会抛出异常,但是Quartz定时器,依然在下一个任务执行时间点执行任务,并没有因为异常,而导致定时器关闭,不再执行循环任务。

 

TimerTask任务类

public class EmailReportTask extends TimerTask{   // 每次执行过程中num的值都会发生变化,说明此事使用的是同一个类对象private int num = 0;    @Override       public void run() {       System.out.println("num = " + num++);    throw new RuntimeException("test");    }     }   
TimerTask输出结果

num = 0Exception in thread "org.springframework.scheduling.timer.TimerFactoryBean#0" java.lang.RuntimeException: testat com.hry.spring.timertask.EmailReportTask.run(EmailReportTask.java:11)at java.util.TimerThread.mainLoop(Unknown Source)at java.util.TimerThread.run(Unknown Source)

TimerTask抛出异常后,后续再也没有执行此任务了,并且定时器所在的线程也自动结束。

 

通过以上的分析,可以知道Quartz的某次执行任务过程中抛出异常,不影响下一次任务的执行,当下一次执行时间到来时,定时器会再次执行任务;而TimerTask则不同,一旦某个任务在执行过程中抛出异常,则整个定时器生命周期就结束,以后永远不会再执行定时器任务

 

 

附件为测试程序







0 0
原创粉丝点击