1. 传统定时器
1.1 Timer
1. 让程序10秒之后执行
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("开始打印。。。");
}
}, 10000);
2. 让程序10秒之后执行,然后没3秒执行一次
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("开始打印。。。");
}
}, 10000,3000);
1.2 TimerTask
1. 让一个定时器2秒执行然后4秒执行,接着再2秒执行然后在4秒执行,如此往复
自定义TimerTask
package com.bjc.thread.demo2;
import java.util.Timer;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask{
private static Integer count = 0;
@Override
public void run() {
count = (count + 1) % 2;
System.out.println("乓!");
new Timer().schedule(new MyTimerTask(), 2000 + 2000 * count);
}
}
调用
package com.bjc.thread.demo2;
import java.util.Date;
import java.util.Timer;
public class TranditionalTimer {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
timer.schedule(new MyTimerTask(), 2000);
while(true){
System.out.println(new Date().getSeconds());
Thread.sleep(1000);
}
}
}
执行结果:
2. 定时框架Quartz
2.1 简介
Quartz是基于java实现的任务调度框架,用于执行力想要执行的任何任务。
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。
官方网址是http://www.quartz-scheduler.org
2.2 Quartz运行环境
1. Quartz可以运行嵌入在另一个独立式应用程序
2. Quartz可以在应用程序服务器(或servlet容器)内被实例化,并且参与事务
3. Quartz可以作为一个独立的程序运行(其自己的java虚拟机内),可以通过RMI使用
4. Quartz可以被实例化,作为独立的项目集群(负载均衡和故障转移功能),用于作业的执行。
2.3 Quartz核心概念
2.3.1 任务Job
Job就是你想要实现的任务类,每一个job必须实现org.quartz.job接口,且只需要实现接口定义的execute()方法。
2.3.2 触发器Trigger
Trigger为你执行任务的触发器,比如你想要每天定时3点发送一份统计邮件,Trigger将会设置3点进行该任务,Trigger主要包含两种SimpleTrigger与CronTrigger两种。
2.3.3 调度器Scheduler
Scheduler为任务调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行job
2.4 入门案例
2.4.1 开发环境准备
新建一个maven工程quartzDemo
2.4.2 添加依赖
添加quartz依赖
在仓库https://www.mvnrepository.com中,搜索quartz,找到quartz与Quartz Jobs的依赖,然后在pom.xml文件中,添加dependencies标签,在该标签下,将quartz的依赖添加进去
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
添加完之后,查看Maven Dependencies下的依赖jar,发现其下有slf4j的接口jar包,所以我们需要添加日志依赖jar
右键——maven——add Dependence,输入slf4,如图
在相同的步骤,输入log4j
最后,添加log4j的配置文件
2.4.3 更改编译环境
依赖添加完毕之后,我们发现编译环境是1.5,我们希望其是1.8,这时候可以添加maven的插件
鼠标右键——maven——add plugin,输入maven-compile
然后,在pom.xml中,对应的compile插件配置的version标签下添加如下配置
<configuration>
<target>1.8</target>
<source>1.8</source>
</configuration>
完整的pom.xml如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.bjc</groupId>
<artifactId>quartzDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 添加依赖 -->
<dependencies>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
<!-- quartz依赖日志接口slf4j-api-1.7.7.jar ,所以也需要log4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.4.4 案例代码
1. 新建Job类
job类需要实现Job
package cn.bjc.quartz.job;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time);
System.out.println("任务开始执行,时间是:" + format);
}
}
2. 新建main执行调度类
分三步走:
1. 调度器(Scheduler),从工厂StdSchedulerFactory中获取
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
注意:这个默认的调度器内部其实是返回new StdSchedulerFactory()
2. 任务实例(JobDetail),通过JobBuilder创建
3. 触发器(Trigger)
代码:
package cn.bjc.quartz.main;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import cn.bjc.quartz.job.HelloJob;
public class HelloSchedulerDemo {
public static void main(String[] args) throws Exception {
// 1. 调度器(Scheduler),从工厂获取
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 内部默认是new StdSchedulerFactory()
// 2. 任务实例(JobDetail),通过JobBuilder创建
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class) // 加载任务类,与HelloJob绑定
.withIdentity("job1", "group1") // 参数一:任务的名称(唯一实例);参数二:任务组的名称,对任务进行分组
.build();
// 3. 触发器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") // 参数一:触发器的名称;参数二:触发器组的名称,对触发器进行分组
.startNow() // 启动时间,这里设置马上启动
.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5))// 每5秒重复执行
.build();
// 最后,让调度器关联任务和触发器,保证按照触发器定义的条件去执行任务。
scheduler.scheduleJob(jobDetail, trigger);
// 启动
scheduler.start();
}
}
运行效果: