序
前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框架中,有两种主要的方法来实现定时任务:Spring自带的`@Scheduled`注解和引入第三方库Quartz。这两种方法都可以帮助开发者在特定的时间点执行任务,为应用程序添加计划任务的能力。 首先,我们来看看使用...
Java定时器和Spring定时器是Java开发中用于执行周期性任务的重要工具,它们在系统维护、数据同步、报告生成等场景中发挥着关键作用。本文将深入探讨这两个概念,以及如何在Spring框架中配置和使用定时器。 首先,...
本篇文章将详细介绍两种使用Spring自身实现轻量级定时器的方法。 方法一:基于`@Scheduled`注解 1. `@Scheduled`注解:这是Spring提供的一个用于声明周期性任务的注解。在Java类中的方法上添加此注解,Spring会...
总结来说,Spring定时器提供了两种方式来创建和执行定时任务:基于Timer的简单定时任务和基于Quartz的高级定时任务。Timer适用于简单的定时需求,而Quartz更适合需要精确控制任务执行时间和周期的复杂场景。在实际...
在Spring框架中,实现定时任务有两种主流方式:使用`java.util.Timer`类或集成第三方库如Quartz。这两种方法各有优势: - **Java Timer**:简单易用,适合简单的定时任务需求。 - **Quartz**:功能强大且灵活,支持...
Spring框架和Java内置的定时器提供了两种不同的方式来实现这样的功能。 首先,我们来看Spring定时器。Spring使用的是Quartz库来实现定时任务管理。在给出的例子中,可以看到配置文件中定义了几个关键的bean: 1. `...
Spring 定时器两种实现方式 Spring 定时器是 Spring 框架中的一种组件,用于实现定时任务的执行。它提供了两种实现方式:Java Timer 定时和 Quartz 定时器。在本文中,我们将详细介绍这两种实现方式的原理、优点和...
本篇文章将详细讲解两种在Spring MVC框架中实现定时任务的方法:Spring MVC自带的定时器以及Quartz与Spring的集成。 首先,我们来看看Spring MVC自带的定时任务。Spring MVC作为Spring框架的一个模块,主要处理HTTP...
Spring框架提供了两种方式来处理定时任务:Java内置的`Timer`类和第三方库OpenSymphony的Quartz。下面将详细介绍这两种实现方式。 ### 1. Java `Timer` 类 Java `java.util.Timer` 类是Java标准库中的一个轻量级...
这两种方法都可以有效地在Spring Boot中实现定时任务的功能。第一种方法更为常见,因为它允许你在主类中直接启用定时任务功能;而第二种方法则可以让主类保持简洁,适合那些希望将定时任务与业务逻辑分离的场景。...
在Spring中,AOP的实现主要有两种方式:基于代理的AOP(Proxy-based AOP)和基于字节码的AOP(Bytecode-based AOP)。基于代理的AOP主要使用JDK动态代理或CGLIB库来创建代理对象,而基于字节码的AOP则使用AspectJ库...
在Spring框架中,定时任务的实现通常有多种方式,这里主要讨论的是两种常见的方式:Java Timer和Quartz定时器。这两种方法都有其特点和适用场景,开发者可以根据项目需求来选择。 1. **Java Timer定时器** Java ...
在Java编程语言中,`Timer`类和Spring框架的定时任务是两种常见的实现定时执行任务的方式。本篇文章将深入探讨这两个主题,旨在帮助初学者理解它们的工作原理以及如何在实际项目中应用。 首先,让我们来看一下Java...
Spring支持两种方式来定义定时任务:一种是使用`@Scheduled`注解,另一种是通过实现`Runnable`接口并注册到`TaskScheduler`。 1. **使用`@Scheduled`注解**: 在你的服务类中,你可以为需要定时执行的方法添加`@...
本篇文章将详细探讨两种实现Spring定时任务的方法:基于Java内置的`TimerTask`和第三方库Quartz Scheduler。 首先,让我们看看如何使用`TimerTask`来实现Spring中的定时任务。`TimerTask`是Java的标准库类,它提供...
首先,Spring提供了两种主要的定时任务解决方案:一是Spring内置的`TaskScheduler`接口,二是基于Quartz库的`@Scheduled`注解。`TaskScheduler`提供了一种异步执行任务的方式,适合于简单的定时任务需求。而`@...
以下是两种方式的使用: 1. **基于Java配置的@Scheduled** ```java @Configuration @EnableScheduling public class AppConfig { @Bean public MyTask myTask() { return new MyTask(); } @Scheduled...
首先,理解Spring定时器的基础概念。Spring提供了两种定时任务框架:`java.util.Timer`和`@Scheduled`注解。然而,对于复杂的企业级应用,Quartz更具有优势,因为它支持集群、灵活的调度策略和丰富的API。 1. **...
Spring定时器基于Java的`java.util.Timer`和`java.util.TimerTask`,但更进一步,它支持Quartz和SimpleScheduler这两种强大的定时任务库。Quartz是一个开源的作业调度框架,而SimpleScheduler则内置在Spring中,适用...