Spring4定时器 cronTrigger和simpleTrigger实现方法
spring4定时器 cronTrigger和simpleTrigger实现方法
Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz 允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。
SimpleTrigger 当需要在规定的时间执行一次或在规定的时间段以一定的时间间隔重复触发执行Job时,SimpleTrigger就可以满足要求;SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔,重复次数属性的值可以为0、正整数、或常量 SimpleTrigger.REPEAT_INDEFINITELY,重复的时间间隔属性值必须为0或长整型的正整数,以毫秒作为时间单位,当重复的时 间间隔为0时,意味着与Trigger同时触发执行(或几乎与Scheduler开始时同时触发执行)。如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒钟触发一次直到指定的结束时间的 Trigger,而无需去计算从开始到结束的所重复的次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性 值即可(我们也可以指定一个比在指定结束时间到达时实际执行次数大的重复次数)。
CronTrigger 支持比 SimpleTrigger 更具体的调度,而且也不是很复杂。基于 cron 表达式,CronTrigger 支持类似日历的重复间隔,而不是单一的时间间隔。
Cron 表达式包括以下 7 个字段:
格式: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , - * / 2 分 是 0-59 , - * / 3 小时 是 0-23 , - * / 4 日 是 1-31 , - * ? / L W 5 月 是 1-12 or JAN-DEC , - * / 6 周 是 1-7 or SUN-SAT , - * ? / L # 7 年 否 empty 或 1970-2099 , - * /
Quartz官方网站对SimpleTrigger和CronTrigger的简单对比: SimpleTrigger is handy if you need 'one-shot' execution (just single execution of a job at a given moment in time), or if you need to fire a job at a given time, and have it repeat N times, with a delay of T between executions.当你需要的是一次性的调度(仅是安排单独的任务在指定的时间及时执行),或者你需要在指定的时间激活某个任务并执行N次,设置每次任务执行的间隔时间T。那此时使用SimpleTrigger将是非常方便的。
CronTrigger is useful if you wish to have triggering based on calendar-like schedules - such as "every Friday, at noon" or "at 10:15 on the 10th day of every month."如果你需要安排的任务时基于日期的-比如"每个星期五正午"或者"每个月10号的10:15",使用CronTrigger将是非常有用的。
1、配置applicationcontext.xml
<!-- cronTrigger实现方式 -->
<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.ouku.entities.report.ReportTimerTask" />
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="3600" />
</map>
</property>
</bean>
<bean id="springUtil" class="com.ouku.util.SpringUtil" />
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="exampleJob" />
<!-- run every morning at 6 AM -->
<!-- <property name="cronExpression" value="0 0 6 * * ?" /> -->
<!-- <property name="cronExpression" value="0 0/1 * * * ?" /> --><!-- 每分钟 -->
<property name="cronExpression" value="0/5 * * * * ?" /> <!-- 每秒 -->
</bean>
<bean id="exampleBusinessObject" class="com.ouku.entities.report.ReportTimerTaskTwo" />
<bean id="jobDetail"
<!-- simpleTrigger实现方式 -->
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject" />
<property name="targetMethod" value="doIt" />
<property name="concurrent" value="false" />
</bean>
<bean id="simpleTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<!-- see the example of method invoking job above -->
<property name="jobDetail" ref="jobDetail" />
<!-- 0 seconds -->
<property name="startDelay" value="0" />
<!-- repeat every 5 seconds -->
<property name="repeatInterval" value="5000" />
</bean>
<!-- 总调度用于启动Spring定时器 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<ref bean="simpleTrigger"/>
</list>
</property>
</bean>
其中<property name="concurrent" value="false" />
- 设置为false时,定时任务会串行执行;就是定时任务开启时,知道这个job结束,才会执行下一个定时任务;
- 设置为true时,定时任务会并发执行,就是不管这个job有没有执行完,定时任务都会启动,如果没有执行完,定时任务会开一个新的线程来执行job,确保能在设定的时间间隔内执行job;定时器默认最多有十个线程,当十个线程都用完时,定时任务会阻塞,直到有新的线程可用,才会开启定时任务去执行job;
2.利用cronTrigger的Java实现
package com.ouku.entities.report;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.ouku.report.ReportTask;
public class ReportTimerTask extends QuartzJobBean {
private int timeout;
public void setTimeout(int timeout) {
this.timeout = timeout;
}
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
try {
Date date = new Date();
String dd = " " + date.getMinutes() + ":" + date.getSeconds() + " ";
System.out.println("AAA" + dd);
//to do
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.利用simpleTrigger的Java实现
package com.ouku.entities.report;
import java.util.Date;
import org.quartz.JobExecutionException;
import com.ouku.report.ReportTask;
public class ReportTimerTaskTwo {
public void doIt() throws JobExecutionException {
try {
Date date = new Date();
String dd = " " + date.getMinutes() + ":" + date.getSeconds() + " ";
System.out.println("sss1" + dd);
//to do ..
} catch (Exception e) {
e.printStackTrace();
}
}
}
在使用并发的情况下,当Job执行时间超过间隔时间时,调度框架为了能让任务按照我们预定的时间间隔执行,会马上启用新的线程执行任务。
再次强调,spring4 quartz最多可以为我们开启十个线程,当我们需要执行的任务有锁的情况下,那么在十个线程用完之后,定时器没有线程可以开启,这时候就会出现定时任务的时间间隔超过我们设定的时间间隔;
我们怎么解决这个情况呢?
一、优化我们执行的job,使其在设定的时间间隔内执行完;
二、设置时间间隔更长一点;
我们再来看看串行执行和并发执行的区别:
下面是串行执行时,每个线程的执行情况:
我们可以看到,每个定时任务是在job完成之后才会开启新的线程来执行下一个job;
下面看看并发执行,每个线程执行的情况:
我们可以看到,定时任务是按照我们设置的时间间隔执行的,不会在意job是否执行完,如果没有执行完,定时任务会开启一个新的线程来执行job;
- html5打开摄像头
- UWP基础教程 - App多语言支持
- Golang实现Fibonacii的几种算法
- 【译】使用 dotnet watch 开发 ASP.NET Core 应用
- vmware安装ubuntu12.04嵌套安装xen server(实现嵌套虚拟化)
- Golang语言切片slice的线程协程安全问题
- ASP.NET Core 在 Azure 开启 HTTPS
- 算法基础:最大递减数问题(Golang实现)
- 亲身经历的痛--database/sql: Stmt的使用以及坑
- Ubuntu上通过nginx部署Django笔记
- Go学习笔记:golang交叉编译
- Python魔术方法-Magic Method
- python类中super()和__init__()的区别
- Python正则表达式:最短匹配
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 微信群总是有人发广告?看我用Python写一个自动化机器人消灭他!
- 苏宁基于 ClickHouse 的大数据全链路监控实践
- CORS Cross Origin Resource Sharing
- 从0开始做播放器-第二季-第2章-Android NDK 工程的建立和 JNI 的基本用法
- 记一次线上问题排查-maven父子结构依赖所遇到的坑
- 『技术随手学』解决 pip conda install 网络故障中断
- boost asio
- 7.SwrContext音频重采样使用
- 8.ffmpeg-基础常用知识
- 9.下载ffmpeg、使QT支持同时编译32位和64位
- 10.QT-QAudioOutput类使用
- 11.QT-ffmpeg+QAudioOutput实现音频播放器
- Spring JPA 自定义删改
- LeetCode-28.实现 strStr()
- 【工具篇】程序员不愿意写 PPT 是姿势不对?