文档章节

使用Quartz作为任务调度时 fireTime的一个坑

caiw
 caiw
发布于 2015/02/01 16:53
字数 867
阅读 59
收藏 0

         一个任务调度的业务场景:需要在每个小时后2秒钟从数据库中取得当前小时的数据并进行计算,此时使用Quartz做为任务调度,设置每个小时执行一次,sleep2秒以后执行业务代码。并使用Quartz提供的fireTime作为时间条件获取数据。

先看示例代码:

public class QuartzTest {
	public static void main(String[] args) throws SchedulerException {
		//String cron="00 00 * * * ?";
		//为了测试使用就近时间。
		String cron="00 17 * * * ?";
		StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory(); 
		Scheduler stdSchedulerFactory=sf.getScheduler();
	       //50个任务
		for(int i=1;i<50;i++){
			JobDetail jobDetail=JobBuilder.newJob(Job1.class).build();
			Trigger trigger=TriggerBuilder.newTrigger()
					.withSchedule(CronScheduleBuilder.cronSchedule(cron))
					.build();
			sched.scheduleJob(jobDetail,trigger);
		}
		sched.start();
	}

}

Job1.class

public class Job1  implements Job{
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String dateStr=sf.format(context.getFireTime());
		//记录任务调度的时间
		System.out.println(dateStr);
		try {
		    Thread.sleep(2000);
	            //do someting  with dateStr.... 
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

得到的结果:

2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:00
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:01
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:02
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:03
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04
2015-02-01 04:27:04

通过结果发现 拿到的fireTime和预期不一样。

这个时候如果使用fireTime去获取数据就会拿到有误差的数据,也会造成业务结果错误。

通过分析发现 Quartz(v2.1.1) 默认使用的是自带线程池的实现:SimpleThreadPool,并且默认为10个线程,在并发任务达到 10 个以后,再有触发的任务就无法被执行了,只能等待有空闲线程的时候才能得到执,这也是为什么结果中只有前10个结果是符合预期的。

我们可以添加配置文件来修改Quartz的一些默认配置项,并发数:

org.quartz.threadPool.threadCount=50;

也可以直接在代码中修改:

StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory(); 
Properties pro=new Properties();
pro.setProperty("org.quartz.threadPool.threadCount", "50");
stdSchedulerFactory.initialize(pro);

 但是必须指出一点,这个初始线程数并不是越大越好。当并发线程太多时,系统整体性能反而会下降,因为系统把很多时间花在了线程调度上。

© 著作权归作者所有

共有 人打赏支持
caiw
粉丝 2
博文 15
码字总数 5222
作品 0
成都
私信 提问
Quartz任务调度源码分析

从源码分析中可以看出,任务的整个调度过程为,初始化线程池,及调度器QuartzScheduler,然后由线程池去执行QuartzSchedulerThread,将触发器任务(job与触发器)添加到存储器(TreeSet,timeT...

sgkbkega
2016/09/08
17
0
如何高效排查日均调度量超两百万次的重复调度问题? | 技术头条

作者 | 余慧娟 责编 | 郭芮 系统自从改用Quartz做任务调度后,一日的调度量均在两百万次以上。随着调度量的增加,突然开始出现job重复调度的情况,且没有规律可循。网上也没有说得较为清楚的...

CSDN资讯
09/09
0
0
基于 Quartz 开发企业级任务调度应用

简介: Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。作为一个优秀的开源调度框架,Quartz 具有功能强大,应用灵活,易于集成的特点。本文剖析了 Qu...

IBMdW
2013/05/19
13.5K
29
quartz集群

其实主要还是借鉴别人的东东,写的还挺好的。我自己只在最后说说自己遇到的坑吧。 1、Quartz任务调度的基本实现原理   Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基...

梦蝶飘雪
2016/08/12
188
0
基于quartz的云调度中心实现

一、背景 作为业务开发人员,会经常需要写一个定时任务。目前,写定时任务应用最广泛最成熟的方案是OpenSymphony开源组织在任务调度领域的一个开源项目quartz,比如要写一个定时数据同步任务...

zjytk05
2016/05/19
0
33

没有更多内容

加载失败,请刷新页面

加载更多

走上真正的教育之路——《中国最美的语文》读后感3100字

走上真正的教育之路——《中国最美的语文》读后感3100字: 文:张平。《中国最美的语文》,乍一听,你可能会觉得这个作者或者编辑有些大言不惭,竟然起这么大而狂的名字,可能名不副实。我没...

原创小博客
26分钟前
2
0
tomcat线程模型

Connector结构 BIO模式 NIO模式

grace_233
46分钟前
2
0
Javascript

变量定义 以$,_,字母开头 大小写敏感 var 关键字声明变量 声明未赋值undefined 数据类型 字符串,数字,布尔,数组,NULL,undefined 变量均为对象 函数 无默认值 var声明的是局部变量 函数外声明...

关元
48分钟前
1
0
文件系统、服务、防火墙、SELINUX——安全四大金刚

一提到安全,大家都会想到防火墙,和文件系统权限。而实际工作环境中,我们在Linux的安全配置,会涉及到四个级别。我们思考一个场景,你要在百度盘中存放一个文件,这个动作需要考虑下面四个...

Linux就该这么学
49分钟前
3
0
从源码角度理解Java设计模式——门面模式

一、门面模式介绍 门面模式定义:也叫外观模式,定义了一个访问子系统的接口,除了这个接口以外,不允许其他访问子系统的行为发生。 适用场景:子系统很复杂时,增加一个接口供外部访问。 优...

我叫刘半仙
58分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部