java quartz timer_java定时任务实现的几种方式(Timer、Spring Task、Quartz)
Timer
JDK自带的Timer类,允许调度一个TimerTask任务。
Demo:
/*** Timer测试类
*/
public classTimerDemo {
public static voidmain(String[] args) {
//创建定时器
Timer timer = newTimer();
//添加调度任务
//schedule(TimerTask task, Date time); 特定时间 time 执行
//timer.schedule(new MyTask(), new Date(System.currentTimeMillis() + 1000));
//schedule(TimerTask task, long delay); //延迟 delay毫秒 执行 task
//timer.schedule(new MyTask(), 1000);
//schedule(TimerTask task, long delay, long period) 延迟 delay毫秒 执行并每隔 period毫秒 执行一次
//timer.schedule(new MyTask(), 1000, 5000);
//schedule(TimerTask task, Date time, long period); 特定时间 time 执行并每隔 period毫秒 执行一次
timer.schedule(new MyTask(), new Date(System.currentTimeMillis() + 1000), 5000);
}
}
/*** 具体执行的任务
*/
public class MyTask extendsTimerTask {
/*** The action to be performed by this timer task.
*/
public voidrun() {
System.out.println("执行时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
}
}
Spring Task:
Spring3.0以后自主开发的定时任务工具Spring Task,支持线程池,可以高效处理许多不同的定时任务,除spring相关的包外不需要额外的包,支持注解和配置文件两种形式。 但不能处理过于复杂的任务 。
基于配置的Demo:
定时任务类:
/*** spring执行任务的类
*/
public classSpringTask {
public voidshow1() {
System.out.println("show1:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
}
public voidshow2() {
System.out.println("show2:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
}
}
配置文件spring-schedule.xml:
基于注解的Demo:
定时任务类:
/*** spring执行任务的类
*/@Component
public classSpringAnnoTask {
@Scheduled(cron = "1-10 * * * * ? ")//每分钟的1-10秒每秒执行一次
public voidshow1() {
System.out.println("show1:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
}
@Scheduled(cron = "0/10 * * * * ? ")//每10秒执行一次
public voidshow2() {
System.out.println("show2:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
}
}
配置文件spring-schedule.xml:
Quartz
这个就厉害了,这篇文章只能简单介绍个入门案例,如果需要深入研究请自行查看官方文档或者网上找些系列的文章。w3cschool文档
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
特点:
强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求;
灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;
分布式和集群能力,Terracotta 收购后在原来功能基础上作了进一步提升。
另外,作为 Spring 默认的调度框架,Quartz 很容易与 Spring 集成实现灵活可配置的调度功能。
核心元素 :
Scheduler: 任务调度器,是实际执行任务调度的控制器。在spring中通过SchedulerFactoryBean封装起来。
Trigger :触发器,用于定义任务调度的时间规则,有SimpleTrigger,CronTrigger,DateIntervalTrigger和NthIncludedDayTrigger,其中CronTrigger用的比较多,本文主要介绍这种方式。CronTrigger在spring中封装在CronTriggerFactoryBean中。
Calendar:它是一些日历特定时间点的集合。一个trigger可以包含多个Calendar,以便排除或包含某些时间点。
Job:任务,是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中。实现Job接口的任务,默认是无状态的,若要将Job设置成有状态的,在quartz中是给实现的Job添加@DisallowConcurrentExecution注解(以前是实现StatefulJob接口,现在已被Deprecated),在与spring结合中可以在spring配置文件的job detail中配置concurrent参数。
JobDetail :任务信息,用来描述Job实现类及其它相关的静态信息,如Job名字、关联监听器等信息。在spring中有JobDetailFactoryBean和 MethodInvokingJobDetailFactoryBean两种实现,如果任务调度只需要执行某个类的某个方法,就可以通过MethodInvokingJobDetailFactoryBean来调用。
Trigger触发器 :
SimpleTrigger :在一个指定时间段内执行一次作业任务或是在指定时间间隔内执行多次作业任务;
CronTrigger :基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用。
简单案例:
jar包依赖:
org.quartz-scheduler
quartz
2.2.1
org.quartz-scheduler
quartz-jobs
2.2.1
具体定时任务需要执行的类:
/*** 具体执行的任务 实现Job接口
*/
public class MyDemoJob implementsJob {
public void execute(JobExecutionContext jobExecutionContext) throwsJobExecutionException {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//当前时间
System.out.println("执行时间:" + sf.format(newDate()));
//获取Trigger
Trigger trigger =jobExecutionContext.getTrigger();
//通过trigger获取job标识
JobKey jobKey =trigger.getJobKey();
System.out.println("Job's key:" + "name:" + jobKey.getName() + "\tgroup:" +jobKey.getGroup());
//getClass();
System.out.println("Start time : " +sf.format(trigger.getStartTime()));
//System.out.println("End time : " + sf.format(trigger.getEndTime()));
}
}
基础Demo:
/*** 基础触发器调度程序
*/
public classBaseScheduler {
public static voidmain(String[] args) {
try{
//1. 创建一个JodDetail实例 将该实例与具体要执行的job类 MyDemoJob.class绑定
JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class) //定义Job类为MyDemoJob类(具体执行定时任务的内容)
.withIdentity("myJob", "default") //定义name/group
.build();
//2. 定义一个Trigger,10秒后执行
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate()));
//2.1 设置开始时间
Date startTime = newDate();
startTime.setTime(startTime.getTime() + 10000L);
//2.2 设置结束时间
//Date endTime = new Date();
//endTime.setTime(endTime.getTime() + 20000L);
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "default")//定义名字和组
.startAt(startTime)
//.endAt(endTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
//上面这句的意思是 这个定时器每5秒执行一次 直到山峰没有棱角 河水不再流 详细使用请查看withSchedule的参数设置
.build();
//3. 创建scheduler 从StdSchedulerFactory工厂中获取
Scheduler scheduler =StdSchedulerFactory.getDefaultScheduler();
//4. 将jobDetail和trigger加入这个调度(注册 任务详情和触发器)
scheduler.scheduleJob(jobDetail, trigger);
//5. 启动scheduler
scheduler.start();
} catch(SchedulerException e) {
e.printStackTrace();
}
}
}
基于SimpleTrigger的Demo:
/*** SimpleTrigger 简单触发器调度程序
*/
public classSimpleTriggerScheduler {
public static voidmain(String[] args) {
try{
//1. 创建一个JodDetail实例
JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class)
.withIdentity("myJob")
.build();
//2. 定义一个Trigger
Date startTime = newDate();
startTime.setTime(startTime.getTime() + 5000L);
SimpleTrigger trigger =(SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")//定义名字和组
.startAt(startTime)
.build();
//3. 创建scheduler
Scheduler scheduler =StdSchedulerFactory.getDefaultScheduler();
//4. 将jobDetail和trigger加入这个调度(注册 任务详情和触发器)
scheduler.scheduleJob(jobDetail, trigger);
//5. 启动scheduler
scheduler.start();
} catch(Exception e) {
e.printStackTrace();
}
}
}
基于CronTrigger的Demo:
/*** CronTrigger 基于Cron表达式的触发器调度程序
*/
public classCronTriggerScheduler {
public static voidmain(String[] args) {
try{
//1. 创建一个JodDetail实例
JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class)
.withIdentity("myJob") //定义name/group
.build();
//2. 定义一个Trigger 使用Cron表达式来控制运行
CronTrigger trigger =(CronTrigger) TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule( //定义任务调度的时间间隔和次数
CronScheduleBuilder
.cronSchedule("0/10 * * * * ? ")//每10秒运行一次
)
.build();
//3. 创建scheduler
SchedulerFactory sfact = newStdSchedulerFactory();
Scheduler scheduler =sfact.getScheduler();
//4. 将jobDetail和trigger加入这个调度(注册 任务详情和触发器)
scheduler.scheduleJob(jobDetail, trigger);
//5. 启动scheduler
scheduler.start();
} catch(Exception e) {
e.printStackTrace();
}
}
}
PS:Cron表达式介绍
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
(1)Seconds Minutes Hours DayofMonth Month DayofWeek Year
(2)Seconds Minutes Hours DayofMonth Month DayofWeek
各个字段的含义:
字段
允许值
允许的特殊字符
秒(Seconds)
0~59的整数
, - * / 四个字符
分(Minutes)
0~59的整数
, - * / 四个字符
小时(Hours)
0~23的整数
, - * / 四个字符
日期(DayofMonth)
1~31的整数(但是你需要考虑你月的天数)
,- * ? / L W C 八个字符
月份(Month)
1~12的整数或者 JAN-DEC
, - * / 四个字符
星期(DayofWeek)
1~7的整数或者 SUN-SAT (1=SUN)
, - * ? / L C # 八个字符
年(可选,留空)(Year)
1970~2099
, - * / 四个字符
每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:
(1)*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。
(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。
例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。
(3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
(4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
(5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
(6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。
例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;
如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。
java quartz timer_java定时任务实现的几种方式(Timer、Spring Task、Quartz)相关推荐
- SpringBoot定时任务实现的两种方式介绍
今天给大家介绍SpringBoot定时任务实现的几种方式,希望对大家能有所帮助! 1.SpringTask 用法 框架介绍:SpringTask是Spring自带的轻量级定时任务工具,相比于Quart ...
- 定时任务实现的几种方式
定时任务实现的几种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行, ...
- Java异步非阻塞编程的几种方式
简介: Java异步非阻塞编程的几种方式 一. 从一个同步的Http调用说起 一个很简单的业务逻辑,其他后端服务提供了一个接口,我们需要通过接口调用,获取到响应的数据. 逆地理接口:通过经纬度获取这个 ...
- 【java】Java运行时动态生成类几种方式
1.概述 转载:Java运行时动态生成类几种方式 这里发现自己不知道的,原来Java 还能自己编译自己,学到了. 最近一个项目中利用规则引擎,提供用户拖拽式的灵活定义规则.这就要求根据数据库数据动态生 ...
- java的如何创建js_[Java教程]JS创建事件的三种方式(实例)
[Java教程]JS创建事件的三种方式(实例) 0 2016-05-11 14:00:16 1.普通的定义方式 οnclick="Sfont=prompt('请在文本框中输入红色','红色' ...
- Java中线程的创建有两种方式
Java中继承thread类与实现Runnable接口的区别 Java中线程的创建有两种方式: 1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2. 通过 ...
- Java实现回文串的四种方式
Java实现回文串的两种方式 1.什么是回文串? "回文串"是一个正读和反读都一样的字符串,如"level"或者"noon"等就是回文串. ...
- Java中遍历Map集合的5种方式总结
这篇文章主要给大家介绍了关于Java中遍历Map集合的5种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值. 方式一 通过Map.keySet使用iterator遍历 ...
- 读取Java文件到byte数组的三种方式及Java文件操作大全(包括文件加密,String加密)
读取Java文件到byte数组的三种方式 package zs;import java.io.BufferedInputStream; import java.io.ByteArrayOutputSt ...
最新文章
- Gym 101741 K(AC自动机)
- 基于netty实现mq
- 从零开始入门 K8s| 阿里技术专家详解 K8s 核心概念
- 重新探讨一下《APEX英雄》系统设计的亮点
- java压缩_Java压缩
- mysql udb_MySQL InnoDB的一些参数说明
- sdk和api有什么区别
- JavaScript 详说事件流(冒泡、捕获、传播、委托)
- 【读书笔记《Android游戏编程之从零开始》】13.游戏开发基础(Paint 画笔)
- 3U VPX导冷高性能SRIO/以太网数据交换板
- 菜鸟学运筹学----引
- Java中级面试题及答案(120道Java中级面试题大汇总)
- Python | 实现双色球选号(educoder)
- 条件期望的测度论解释
- ESP32播放MP3音乐-无需SD卡-WM8978-ESP32解码MP3
- openpyxl不能读取xls格式
- 实战腾讯云ORC文字识别
- LeetCode精选101刷题必备(C++)-附详细分类及解体说明
- 文字转化为二维码(数据加密)
- java 混淆war,java yguard混淆web工程