序
前2篇文章介绍了spring的两种定时器:TimerTask 和 Quartz,本篇要在这两篇的基础上,讲讲两者的区别。
精确度和功能
Quartz可以通过cron表达式精确到特定时间执行,而TimerTask不能。Quartz拥有TimerTask所有的功能,而TimerTask则没有。
任务类的数量
TimerTask和Quartz每次执行任务时,每次调用的是不是都是同一个任务类对象,还是每次都不一样?现在做如下实验,每次执行任务时,将任务类对象本身打印出来。
Quartz任务类
public class MyJob extends QuartzJobBean {
private String sTest;
@Override
protected void executeInternal(JobExecutionContext job)
throws JobExecutionException {
// TODO Auto-generated method stub
System.out.println("sTest = " + sTest);
System.out.println("MyJob Run..." + this);
}
// set/get 略
}
Quartz输出结果
sTest = 10
MyJob Run...com.hry.spring.timertask.MyJob@1060478
sTest = 10
MyJob Run...com.hry.spring.timertask.MyJob@db4fa2
sTest = 10
MyJob 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 = 0
com.hry.spring.timertask.EmailReportTask@1581593
PageReportTask Run...
num = 1
com.hry.spring.timertask.EmailReportTask@1581593
PageReportTask Run...
从输出结果可以看出,TimerTask每次执行时,都是使用同一个对象
从以上的分析,可以得出结论:Quartz每次执行任务都创建一个新的任务类对象,而TimerTask则每次使用同一个任务类对象。
对异常的处理
一个循环执行的任务,如果某一次执行任务时,因为某些原因抛出异常,则定时器是否还会在下一个执行任务的时间点执行任务吗?下面通过模拟在任务类中抛出异常,来模拟这种情况,并测试两种定时器如何处理这种情况。
Quartz任务类
public class MyJob extends QuartzJobBean {
private String sTest;
@Override
protected void executeInternal(JobExecutionContext job)
throws JobExecutionException {
// TODO Auto-generated method stub
System.out.println("sTest = " + sTest);
System.out.println("MyJob Run..." + this);
throw new RuntimeException("Test");
}
// set/get 方法略
}
Quartz输出结果
sTest = 10
MyJob Run...com.hry.spring.timertask.MyJob@16f25a7
2013-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: Test
at 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: Test
at 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
2013-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: Test
at 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: Test
at 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 = 0
Exception in thread "org.springframework.scheduling.timer.TimerFactoryBean#0" java.lang.RuntimeException: test
at 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则不同,一旦某个任务在执行过程中抛出异常,则整个定时器生命周期就结束,以后永远不会再执行定时器任务。
附件为测试程序
分享到:
相关推荐
使用spring 实现的两种定时任务,使用eclipse直接导入就可使用
spring定时器Spring定时器的两种实现方式Java的Timer类和OpenSymphony的Quartz。
spring 定时器 内含TimerTask实现和Quartz实现两种方式
定时器的配置文件(两种方式:springmvc自带定时,Quartz与spring结合的定时)
spring定时器两种实现方式 ,Spring quartz java 定时器 定时任务
NULL 博文链接:https://wenkaixuan.iteye.com/blog/1821342
Spring定时器的两种实现方式.doc
本文向您介绍Spring定时器的两种实现方式,包括Java Timer定时和Quartz定时器,两种Spring定时器的实现方式各有优点,可结合具体项目考虑是否采用。
如何在springboot中添加定时器,让程序定时运行。
并非应用系统中发生的所有事情都是由用户的动作引起的。...在Spring中有两种流行配置:Java的Timer类和OpenSymphony的Quartz来执行调度任务。下面以给商丘做的接口集抄900到中间库的日冻结数据传输为例:
Spring两种定时器实例配置:Java的TimerTask类和OpenSymphony的Quartz。包含5种配置方式:timer普通定时器、timer特定方法定时器、quartz简单定时器、quartz精确定时器、quartz特定方法定时器。简单实用,一看就会。
在我了解的过程中发现java实现定时任务有四种,首先是jdk自带的两个Timer,ScheduledThreadPoolExecutor,后者是jdk1.5提出的,因为这个Timer毛病着实有点多,像什么单线程,出问题了其他任务也执
Spring Cloud简介 Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud0 CloudFoundry、Spring Cloud AWS、Spring Cloud ...
两种方式实现定时执行任务操作,通过spring中集成的timerTask,包含源码及用到的jar包
springboot学习实战 全新内容 新增全新的springboot2的框架技术点(代码位于当前仓库...开启并行多线程任务两种方式 场景案例分析 介绍Springboot2【Tomcat容器自定义】的用法: Tomcat容器配置用法,使用.yml文件方式
+ AOP注解两种模式切面练习 + 项目启动预处理 + 自定义编辑事务架构 + 上传下载 + 传参注解式校验 + session练习 + 公用日志设计封装 + db乐观锁设计 + 优雅启停 + 配置文件信息加密 + AES加解密 + spring 事件监听...
本代码是定时器的实例,两种运行模式,一种是直接以Java程序的形式运行,指定加载的配置文件;另一种是在tomcat下运行
群发or单独 发送短信,支持两种第三方短信商接口 6. spring aop 事物处理 7. 代码生成器 (freemarker), 代码 zip 压缩打包 8. MD5加密 SHA加密(登录密码用此加密) 9. 数据库连接池 阿里的 druid。Druid在监控、...
在工作中有用到spring task作为定时任务的处理,spring通过接口TaskExecutor和TaskScheduler这两个接口的方式为异步定时任务提供了一种抽象。这就意味着spring容许你使用其他的定时任务框架,当然spring自身也提供了...