`

关于Spring中用quartz定时器在定时到达时同时执行两次的问题

阅读更多
我在使用spring的quartz配置定时任务时,发现每次定时时间到达后,指定的定时方法同时执行两次,而且此方法还是使用的synchronized关键字,每次定时一到,会发现此方法内的System.out输出信息输出两次,说明方法在这时执行了两次,解决方法没有找到更好的,不过有一个方法很有效,我设置了一个静态变量,只要此方法一执行,就将变量由0变为1,执行完再设置为0.如果运行方法前检查此静态变量不为0,则return.开发时注意此静态变量不要让别的方法使用.

下面是定时相关的代码:

package org.openjweb.core.schedule;


import org.apache.log4j.Logger;
import org.apache.lucene.demo.IndexHTML;
//import org.apache.lucene.demo.IndexHTML;
import org.openjweb.core.service.ServiceLocator;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class JobSchedule extends QuartzJobBean
{
static Logger logger = Logger.getLogger(JobSchedule.class);
static long counter = 0;  //计数器
//static long priorTime = System.currentTimeMillis();
static int searchIndexFlag =0;//由doBuildIndex修改,其他方法不要修改此参数

public synchronized void doTimerSchedule()
{
  counter++;
  //System.out.println("测试定时器,总计数:"+String.valueOf(counter));
}

protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
  // TODO Auto-generated method stub

}


public synchronized void doBuildIndex()
{
  //定时器同时调用两次的问题需要查找原因
  if(searchIndexFlag>0)return ;//保证同一时刻只有一个定时器运行,通过这种方式保证每次定时时间到时,只执行一个线程
  searchIndexFlag = 1;//锁定
  System.out.println("开始构造索引库....");
     String indexPath = ServiceLocator.getSysConfigService().getStringValueByParmName("luceneIndexDir");
  String filePath = ServiceLocator.getSysConfigService().getStringValueByParmName("searchRoot");
  System.out.println("索引路径为:"+indexPath);
  System.out.println("搜索路径为:"+filePath);
 
  IndexHTML.buildIndex(indexPath,filePath);
  System.out.println("索引库构造完毕!");
  searchIndexFlag = 0;//锁定解除
}

}

使用静态变量标志的方式解决了同一时刻调用两次方法的问题,但我想Spring应该有办法配置只能同一时刻运行一次,是什么造成的定时执行两次呢?大家有没有发现这种问题,欢迎赐教.下面是我在spring的配置:

  <!-- Timer schedule -->
    <bean id="defaultTimerBean" class="org.openjweb.core.schedule.JobSchedule"/>
    <bean id="defaultTimerMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="defaultTimerBean" />
        <property name="targetMethod" value="doTimerSchedule" />
        <property name="concurrent" value="false" /> <!--将并发设置为false-->
    </bean>
    <bean id="defaultTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="defaultTimerMethod" />
        <!--每三分钟的第一分钟触发-->
        <property name="cronExpression" value="0 1/3 * * * ?" />
    </bean>
   
    <bean id="luceneTimerMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="defaultTimerBean" />
        <property name="targetMethod" value="doBuildIndex" />
        <property name="concurrent" value="false" /> <!--将并发设置为false-->
    </bean>
    <bean id="luceneTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="luceneTimerMethod" />
        
        <property name="cronExpression" value="0 1/4 * * * ?" />
    </bean>
   
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <!--作业调度器,list下可加入其他的调度器-->
                <ref bean="defaultTrigger"/>
                <ref bean="luceneTrigger"/> 
            </list>
        </property>
    </bean>

http://blog.csdn.net/baozhengw/archive/2009/04/16/4083247.aspx


JonBLu 发表于2009年4月16日 19:06:49  IP:举报
用的是Tomcat吗?把项目从Tomcat下面的目录移出去试试放在tomcat的webapp下可能会出这种情况LostParadise 发表于2009年4月16日 20:26:07  IP:举报
对于Spring和Quartz来说,你的用法是两个job,所以他们根本不关心他们是否同时运行了。本来concurrent是用来控制同时运行两个相同的job的问题的,但是你的是两个job,所以也用不上。所以。。。。既然你有这样的需求,那只能你自己来解决了。zhenglinshuang 发表于2009年4月20日 18:34:50  IP:举报
如果是这样的话,可能说明两点:1.concurrent = false;具体来说对应的只是job的那个执行方法并发控制;(也就是说某个方法在执行完后才可再执行这个非并发方法)so,你这里用了一个job,两个执行方法,...2.jobDeatail调用bean job时,初始化了不同的的job .attend 发表于2009年5月20日 15:11:49  IP:举报
实现StatefulJob接口就可以了。 public class JobSchedule extends QuartzJobBean implements StatefulJobhjjwind 发表于2009年6月22日 9:27:44  IP:举报
我在开发中也遇到了定时器执行两次得情况……但代码移植到其他环境就正常只执行一次了,定时任务到时间点后连续执行两次应该与SPRING定时器本身的设置无关。
分享到:
评论
2 楼 xiaoqiang2008 2013-05-30  
执行两次的原因是什么,好像楼主没弄清楚啊!
是不是在web.xml中同时配置了ContextLoaderListener和DispatcherServlet?假如真是这样的话,需要删掉一个配置,因为你相当于配置了两个spring容器,两个容器分别都执行各自的计划任务,所以同一个计划任务被执行了两次。
ContextLoaderListener是整合struts等其他框架时常用的配置,起加载时执行优先级高,可以在struts加载之前就执行;假如项目中只有spring框架,那仅配置DispatcherServlet就行了。
以上只是个人猜测,希望能有助于碰到类似问题的朋友们!
1 楼 wangqiuyi 2011-12-08  
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <!--作业调度器,list下可加入其他的调度器-->
                <ref bean="defaultTrigger"/>
                <ref bean="luceneTrigger"/> 
            </list>
        </property>
    </bean>

给bean设置个id 应该就没问题了

相关推荐

    spring java 定时器 执行两次 quartz

    当我们遇到Spring定时器执行两次或者更多次的问题时,这通常是由于配置不当或者多线程并发导致的。下面将详细介绍如何使用Spring集成Quartz,以及解决定时任务重复执行的问题。 首先,让我们了解Spring如何配置...

    Spring中的Quartz配置-Spring-定时器-java定时器.doc

    在 Spring 框架中,Quartz 是一个非常流行的开源作业调度器,可以实现任务的定时执行。在本篇文章中,我们将讨论如何在 Spring 中配置 Quartz,以实现 Java 定时器的功能。 Quartz 介绍 Quartz 是一个开源的作业...

    定时器的配置文件(两种方式:springmvc自带定时,Quartz与spring结合的定时)

    本篇文章将详细讲解两种在Spring MVC框架中实现定时任务的方法:Spring MVC自带的定时器以及Quartz与Spring的集成。 首先,我们来看看Spring MVC自带的定时任务。Spring MVC作为Spring框架的一个模块,主要处理HTTP...

    Spring Quartz 定时器示例(Web工程版)

    Spring Quartz 定时器示例(Web工程版),欢迎下载。

    完美解决多应用服务器负载均衡环境下spring quartz同一定时任务重复执行问题

    在多应用服务器负载均衡环境下,Spring Quartz定时任务的重复执行问题是一个常见的挑战。Spring Quartz是一个强大的、开源的作业调度框架,允许开发者定义和执行复杂的定时任务。然而,当多个服务器实例并行运行时,...

    Spring-quartz实现定时器(含代码)

    在Java开发中,Spring框架与Quartz库的结合使用是创建高效、可扩展的定时任务的常见方式。本文将深入探讨如何使用Spring整合Quartz来实现定时器,并提供相关代码示例。 首先,理解Spring框架。Spring是一个开源的...

    spring+quartz定时器

    在Spring 2.0版本中,已经引入了对Quartz的支持,这使得在Spring应用中配置和管理定时任务变得更加简单。 Quartz则是一个开源的作业调度框架,支持复杂的定时规则和并发执行,其核心是基于Job和Trigger的概念。Job...

    spring之quartz定时器

    《Spring与Quartz定时器深度解析》 在Java开发领域,Spring框架因其强大的功能和灵活性而备受推崇。其中,Spring对任务调度的支持是其一大亮点,尤其与Quartz的集成,使得开发者能够方便地实现定时任务。Quartz是一...

    spring注解Quartz定时执行功能

    在Spring框架中集成Quartz库可以实现强大的定时任务管理功能。Quartz是一个开源的作业调度框架,它允许程序创建和管理任务,以便在特定时间自动执行。Spring通过其优秀的依赖注入(DI)和AOP(面向切面编程)特性,...

    使用spring的quartz定时器要用到的jar包

    4. `spring-aop.jar`(可选):如果需要AOP(面向切面编程)支持,例如在定时任务中加入事务管理,那么这个jar包是必要的。 5. `slf4j-api.jar` 和 `slf4j-log4j12.jar`(或相应的日志实现):用于日志记录,Quartz...

    Spring Quartz定时器的jar包

    Spring Quartz定时器是Java开发中常用的一个任务调度框架,它结合了Spring框架的强大功能与Quartz的灵活性,使得开发者能够方便地在应用中实现定时任务。在这个压缩包中,包含了三个核心的jar文件:`quartz-all-...

    spring和quartz的定时器的启动和停止例子

    在IT行业中,Spring框架和Quartz是两个广泛用于任务调度的重要工具。Spring提供了一种集成Quartz的方式,使得我们可以方便地在Spring应用中管理和执行定时任务。本篇将深入探讨如何在Spring中启动和停止Quartz定时器...

    spring2.0 Quartz 执行每天定时任务 普通普是执行任务

    标题中的“spring2.0 Quartz 执行每天定时任务 普通普是执行任务”涉及到的是在Spring 2.0框架中使用Quartz库来创建并执行每天定时任务的场景。Quartz是一款强大的开源作业调度框架,它可以用来按计划执行各种任务,...

    springMvc定时器执行两次

    标题“springMvc定时器执行两次”涉及到的是Spring MVC与Quartz定时任务的集成问题,其中可能存在配置或逻辑上的错误导致定时任务被触发了两次。在Spring MVC应用中,Quartz是一个常用的库,用于实现定时任务的调度...

    spring boot集成quartz定时器

    总结,Spring Boot集成Quartz定时器能够方便地创建和管理定时任务,同时利用Spring的依赖注入,使得Job可以灵活地调用其他服务或组件。这种方式使得我们的任务更加模块化和易于维护。在实际开发中,根据项目需求,...

    spring定时器启动两次原因及解决

    标题中的“spring定时器启动两次原因及解决”指的是在Spring框架中使用了定时任务功能,如Spring Boot的`@Scheduled`注解或者Spring Task模块,但遇到了定时任务被触发执行了两次的问题。这种情况可能是由于配置不当...

    Spring Quartz定时器

    Spring Quartz定时器 Spring Quartz定时器 Spring Quartz定时器 Spring Quartz定时器

    Spring定时器quartz

    Spring定时器Quartz是Java应用中广泛使用的任务调度框架,它允许开发者定义并执行复杂的定时任务。这篇博客可能探讨了如何在Spring框架中集成Quartz,以实现灵活、可扩展的任务调度。 Quartz是一个开源的作业调度...

    配置Spring+quartz定时器.docx

    假设有一个名为`TestBizService`的类,其中包含了一个名为`timeQuartz`的方法,该方法将在定时任务触发时执行。 ```java public class TestBizService { public void timeQuartz() { // 定时任务的具体逻辑 ...

    quartzDaoImp.rar_quartz_spring定时_定时器

    本项目"quartzDaoImp.rar_quartz_spring定时_定时器"提供了一段基于Spring集成Quartz实现定时任务的代码示例,可供学习和交流。 首先,了解Quartz的基本概念。Quartz允许开发者定义“作业”(Job)和“触发器”...

Global site tag (gtag.js) - Google Analytics