spring 集成quartz 部署在tomcat里 任务每次会执行两遍
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring 集成quartz 部署在tomcat里 任务每次会执行两遍相关的知识,希望对你有一定的参考价值。
spring集成quartz 在tomcat里部署项目 为什么启动的时候 任务每次会执行两遍
quartz的配置文件在web.xml 给spring去加载了
你是不是同样的定时器配置了两次?
你定时器扫描的时间间隔是不是太短?tomcat启动的时间大于或等于运行两次的周期时间。
希望对你有帮助!
定时器只配置了一次 而且时间只定了一天的某个时间点 到了时间点后去执行任务
我没有把配置文件配到applicationContext.xml 中 我就是单独写的一个配置文件 然后统一去加载
追答还有你的项目是不是在多台机有启动,比如测试环境有一个(已启动),你自己的开发环境也启动了,配置的时间点是一样的,也会出现同一时间点多次执行。如果还不是,你的配置应该是有问题的,我一直用spring定时器,都没碰到过这样的问题。
参考技术B quartz定时调度框架的定时器没有设置好,请参考配置文件重新设置定时器,事实上在Spring进行初始化的时候会初始化quartz调度框架,但是这个时候任务是不会自动执行的 参考技术C你是不是同样的定时器配置了两次?
你定时器扫描的时间间隔是不是太短?tomcat启动的时间大于或等于运行两次的周期时间。
希望对你有帮助!
http://leitelyaya.iteye.com/blog/854096
如果能解决你的问题,记得采纳喔,虽然解决方案不是我做的,但找起来也挺麻烦的,嘿嘿~~追问
提问之前 已经在网上搜索过了 都没有解决问题 你提供的链接里的问题跟我的不太一样 我现在还只是用工具在tomcat里部署运行 没有打包部署
追答那就不知道了,在很久以前用过这个,现在早忘了;
Quartz与Spring集成——创建调度器
前言
在《Quartz与Spring集成—— SchedulerFactoryBean的初始化分析》一文中介绍过Spring集成Quartz时的初始化过程,其中简单的提到了创建调度器的方法createScheduler。本文将着重介绍Quartz初始化时是如何创建调度器的。
创建调度器
这里从createScheduler的实现(见代码清单1)来分析,其处理步骤如下:
- 设置线程上下文的类加载器;
- 通过单例方法获取SchedulerRepository的实例(见代码清单2);
- 从调度仓库实例SchedulerRepository中查找已经存在的调度器,这里想说的是虽然此实现考虑到了多线程安全问题,不过这种方式效率较低。不如提前初始化,由final修饰,不使用同步语句,避免线程间的阻塞和等待;
- 获取调取器(见代码清单3),其实际上首先从调度器缓存中查找调度器,否则调用instantiate方法创建调度器;
- 检查重新获取的调度器和已经存在的调度器是否相同,如果相同则说明此调度器已经被激活了,将会报出异常。如果调度器是首次被激活,那么将返回此调度器。这里的实现稍微有些拖沓,其实只有当existingScheduler为null时,才会调用instantiate方法创建newScheduler,也只有在这个时候newScheduler才不等于existingScheduler,并且不会抛出异常。因此我们甚至可以省去Scheduler existingScheduler = (schedulerName != null ? repository.lookup(schedulerName) : null);这行代码,而直接将代码清单3中的实现进行修改——当sched为null时才调用instantiate方法创建调度器。
代码清单1
protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName)
throws SchedulerException {
// Override thread context ClassLoader to work around naive Quartz ClassLoadHelper loading.
Thread currentThread = Thread.currentThread();
ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
boolean overrideClassLoader = (this.resourceLoader != null &&
!this.resourceLoader.getClassLoader().equals(threadContextClassLoader));
if (overrideClassLoader) {
currentThread.setContextClassLoader(this.resourceLoader.getClassLoader());
}
try {
SchedulerRepository repository = SchedulerRepository.getInstance();
synchronized (repository) {
Scheduler existingScheduler = (schedulerName != null ? repository.lookup(schedulerName) : null);
Scheduler newScheduler = schedulerFactory.getScheduler();
if (newScheduler == existingScheduler) {
throw new IllegalStateException("Active Scheduler of name '" + schedulerName + "' already registered " +
"in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!");
}
if (!this.exposeSchedulerInRepository) {
// Need to remove it in this case, since Quartz shares the Scheduler instance by default!
SchedulerRepository.getInstance().remove(newScheduler.getSchedulerName());
}
return newScheduler;
}
}
finally {
if (overrideClassLoader) {
// Reset original thread context ClassLoader.
currentThread.setContextClassLoader(threadContextClassLoader);
}
}
}
代码清单2
public static synchronized SchedulerRepository getInstance() {
if (inst == null) {
inst = new SchedulerRepository();
}
return inst;
}
以上是关于spring 集成quartz 部署在tomcat里 任务每次会执行两遍的主要内容,如果未能解决你的问题,请参考以下文章
spring quartz定时任务集群环境下如何实现只在单个节点运行