Java 中已经有一个 timer 类可以用来进行执行计划,定时任务。我们所要做的只是继承 java.util.TimerTask 类。如下所示:
package com.yourcompany.scheduling;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class ReportGenerator extends TimerTask {
public void run() {
System.out.println("Generating report");
//TODO generate report
}
}
class MainApplication {
public static void main(String[] args) {
Timer timer new Timer();
Calendar date = 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);
// Schedule to run every Sunday in midnight
timer.schedule(new ReportGenerator(), // TimerTask
date.getTime(), // Timer
1000 * 60 * 60 * 24 * 7 // delay)
};
这里有几个问题,我们的类继承了TimerTask ,而timerTask 也是实现了 java.lang.Runnable 接口。我们所要做的只是在我们自己的类里重置 run() 方法。所以我们的TimerTask类其实是一种线程,但线程的调度往往不是按照我们希望来实现的,因为一些垃圾收集等原因,我们计划的时间点,却没有执行必要的任务。这样会产生一些问题。虽然,Timer 类也提供了scheduleAtFixedRate() 方法用来在垃圾收集后能够快速的追上任务进度,但这个不一定是我们所需要的。特别是在 一些 J2EE 服务器上 Timer 是无法控制的,因为它不在容器的权责范围内。另外的,这个任务调度也缺乏一些企业级所需要的 特殊 日期定制的功能,以及修改,查找任务的功能。
这里我们要介绍的是一个开源项目:Quartz .
Quartz 定义了两种 基本接口 Job 和 Trigger . 看名字也就知道,我们的任务必须实现 Job, 我们的时间触发器定义在 Trigger 内。 看一个例子也许能更快的了解他的使用方法:package com.yourcompany.scheduling;
import org.quartz.*;
public class QuartzReport implements Job {
public void execute(JobExecutionContext cntxt) //必须实现的方法
throws JobExecutionException {
System.out.println("Generating report - " +
cntxt.getJobDetail().getJobDataMap().get("type"));
//TODO Generate report
}
public static void main(String[] args) {
try {
SchedulerFactory schedFact
new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
sched.start();
JobDetail jobDetail = new JobDetail("Income Report", // 任务名
"Report Generation", // 任务组
QuartzReport.class //任务执行的类
);
jobDetail.getJobDataMap().put("type","FULL");
CronTrigger trigger new CronTrigger(
"Income Report", //触发器名
"Report Generation" //触发器组
);
trigger.setCronExpression( // 触发器时间设定
"0 0 12 ? * SUN"
);
sched.scheduleJob(jobDetail, trigger); // 执行任务
}
catch (Exception e) {
e.printStackTrace();
}
这里面我们可以看到,当我们定义了任务执行 QuartzReport 类后,需要定一个Scheduler类用来执行计划任务。
一个JobDetail 类来描述这个任务的信息,包括任务信息,任务所在组,任务执行的类。
然后还要定义一个 触发器,类似的也包括触发器名,触发器所在组,触发器触发时间设定。
最后是调度器Scheduler类执行计划任务。基本上一个计划任务执行的流程就完成了。
当然,我们还看到了上面红色代表的内容,这些内容主要是提供在job方法执行的时候所需要的参数的提供。这里使用了JobDataMap 类,它其实就是实现了map的特殊应用的一个类,使用方法与Map 很相似。我们可以用 put() 输入参数。在Job类中使用cntxt.getJobDetail()。getJobDataMap()。get("type") 方法获取输入的参数的值。这里的cntxt 是 JobExecutionContext .就是包含任务执行上下文的一个信息类。这样我们的一个基本的任务执行就可以搞定了。
触发器有两类:SimpleTrigger andCronTrigger. .SimpleTrigger主要提供了跟 java.util.Timer 类相似的功能……你可以在里面定义 任务的起始时间,终止时间,任务的执行次数,任务执行的中间间隔 . 而 CronTrigger类主要提供了更高级的任务调度时间设置,例如 每个星期天的早上7点 . CronTrigger的时间设置说明在最后来介绍。
下面我们介绍一下在 J2EE 环境下如何来使用 Quartz .
首先,我们要配置 web.xml ,添加 一下内容,主要是Quartz 的初始化,
<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<display-name>Quartz Initializer Servlet</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()会读取它。配置如下#
# Configure Main Scheduler Properties
#
org.quartz.scheduler.instanceName = TestScheduler
org.quartz.scheduler.instanceId = one
#
# Configure ThreadPool
#
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
#
# Configure JobStore
#
org.quartz.jobStore.misfireThreshold = 5000
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
这里我们使用的 RAMJobStore 存储方式,这样如果我们的web服务器重启的话,我们所有未执行的任务信息都回丢失。当然,我们也有另外的选择,我们可以把这样的信息存储在数据库内,就是使用 JDBCJobStoreTX
#
# Configure ThreadPool
#
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_
#
# Configure Datasources
#
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.maxConnections 5
附:cronExpression配置说明
字段
允许值
允许的特殊字符
秒
0-59
, - * /
分
0-59
, - * /
小时
0-23
, - * /
日期
1-31
, - * ? / L W C
月份
1-12 或者 JAN-DEC
, - * /
星期
1-7 或者 SUN-SAT
, - * ? / L C #
年(可选)
留空, 1970-2099
, - * /
Cron 的小小说明
表示方式
意义
"0 0 12 * * ?"
Fire at 12pm (noon) every day
"0 15 10 ? * *"
Fire at 10:15am every day
"0 15 10 * * ?"
Fire at 10:15am every day
"0 15 10 * * ? *"
Fire at 10:15am every day
"0 15 10 * * ? 2005"
Fire at 10:15am every day during the year 2005
"0 * 14 * * ?"
Fire every minute starting at 2pm and ending at 2:59pm, every day
"0 0/5 14 * * ?"
Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day
"0 0/5 14,18 * * ?"
Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day
"0 0-5 14 * * ?"
Fire every minute starting at 2pm and ending at 2:05pm, every day
"0 10,44 14 ? 3 WED"
Fire at 2:10pm and at 2:44pm every Wednesday in the month of March.
"0 15 10 ? * MON-FRI"
Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday
"0 15 10 15 * ?"
Fire at 10:15am on the 15th day of every month
"0 15 10 L * ?"
Fire at 10:15am on the last day of every month
"0 15 10 ? * 6L"
Fire at 10:15am on the last Friday of every month
"0 15 10 ? * 6L"
Fire at 10:15am on the last Friday of every month
"0 15 10 ? * 6L 2002-2005"
Fire at 10:15am on every last friday of every month during the years 2002, 2003, 2004 and 2005
"0 15 10 ? * 6#3"
Fire at 10:15am on the third Friday of every month
分享到:
相关推荐
Java.util.Timer类是Java标准库提供的一种简单但功能有限的定时任务执行机制。它允许开发者在指定的时间间隔或特定时间点执行任务,非常适合处理一次性或周期性的后台操作。本篇文章将深入探讨如何使用Timer和...
通过以上分析可以看出,`java.util.Timer`和`java.util.TimerTask`组合可以非常方便地实现定时任务的功能。但是需要注意的是,`Timer`和`TimerTask`的设计并不是线程安全的,在多线程环境下使用时需要特别注意同步...
本篇文章将深入探讨Java中的三种主要时间调度实现:`Timer`、`TimerTask`、以及第三方库`Quartz`和`Spring`的定时任务功能。 ### 1. Java `Timer` 和 `TimerTask` `java.util.Timer` 类提供了一个调度任务的方法,...
最基础的是使用`java.util.Timer`类和`java.util.TimerTask`类。`Timer`类用于创建一个定时调度线程,而`TimerTask`则代表要定时执行的任务。以下是一个简单的例子: ```java import java.util.Timer; import java....
`java.util.Timer` 类和`TimerTask` 类是Java的标准库提供的定时任务工具。`Timer` 创建一个后台线程,用于调度任务。以下是如何使用`Timer` 和`TimerTask` 的基本步骤: 1. 创建一个`TimerTask` 的子类并重写`run...
首先,Java内置了`java.util.Timer`和`java.util.TimerTask`类,它们提供了基本的定时任务功能。`Timer`类用于创建一个定时器,而`TimerTask`是可调度的任务类,继承自它即可定义需要定时执行的任务。以下是一个简单...
Java `java.util.Timer` 类是Java标准库中的一个轻量级定时任务工具。它的使用相对简单,适用于简单的定时任务需求。`Timer` 类包含两个主要的方法:`schedule(TimerTask task, Date firstTime)` 和 `schedule...
在这种情况下,可以使用Servlet容器提供的定时任务机制来代替标准的 `java.util.Timer` 类。通常做法是在 Servlet 的 `init()` 方法中安排定时任务,这样可以确保任务与 Web 应用程序的生命周期同步。 例如,可以在...
在Java中,有两种主要的方式来实现定时任务:Java.util.Timer类和java.util.concurrent包下的ScheduledExecutorService接口。下面我们将详细探讨这两种方法。 1. Java.util.Timer类和TimerTask `Timer`类是Java早期...
在Java中实现定时任务有多种方式,其中比较常见的包括Java自带的java.util.Timer类、Quartz和Spring Task。这些方法各有特点,适用于不同的业务场景和技术需求。 首先,Java自带的java.util.Timer类提供了一种简单...
本文将详细介绍两种常见的Java定时器:`java.util.Timer` 和 `Quartz Scheduler`。 ### 一、Time定时器 `java.util.Timer` 是Java标准库中的一个工具类,用于创建和管理定时任务。它提供了一种简单的方式来安排...
首先,Java标准库提供了一个名为`java.util.Timer`和`java.util.TimerTask`的类,它们可以用来创建简单的定时任务。`Timer`类用于调度任务,而`TimerTask`是实际的任务对象。下面是一个简单的例子: ```java import...
Quartz 是一个开源项目,由 OpenSymphony 组织提供,它提供了比 `java.util.Timer` 更加强大和灵活的任务调度功能。 ```java package org.lzstone.action; import org.quartz.Job; import org.quartz....
"小议时序调度Timer和Quartz"这个主题主要关注Java平台上的两种常见定时任务框架:Java内置的`java.util.Timer`类和开源的Quartz库。 首先,让我们详细探讨一下`java.util.Timer`。这个类是Java标准库的一部分,它...
Java提供了一些内置的定时工具,如`java.util.Timer`和`java.util.concurrent.ScheduledExecutorService`,但它们在处理复杂定时任务时可能会显得力不从心。在这种情况下,第三方库Quartz就显得尤为出色。 1. **...
本文将深入探讨如何使用Java标准库中的`java.util.Timer`和`java.util.TimerTask`来实现定时任务。 ### 原理详解 在Java中,`java.util.Timer`类提供了调度定时任务的功能,而`java.util.TimerTask`则是执行这些...
在这个“java定时任务小例子”中,我们可以看到两个关键文件:`TimerTest.java`和`DoTask.java`,它们分别代表了定时器的任务调度和实际执行任务的组件。 首先,我们来看`TimerTest.java`。这个文件很可能是整个...
首先,Java提供了一个内置的定时框架——`java.util.Timer`类和`TimerTask`类,它们可以用来创建简单的定时任务。`Timer`类用于调度任务,而`TimerTask`是执行的任务对象。以下是一个简单的示例: ```java import ...