Spring使用之:Quartz定时任务为什么会被阻塞

    技术2025-09-28  96

    Spring使用之:Quartz定时任务为什么会被阻塞

    文章分类:Java编程 关键字: spring, quartz, 定时任务 问题: 周日,公司CTO给我打电话说,监控系统的数据从下午1点就不更新了。我登录服务器排除了数据同步问题,查看日志也没有例外抛出,查询了前一天的 日志发现几个数据库表空间溢出例外。最后定位,Spring定时任务挂掉了。重启应用恢复正常。周一早上,同样的问题又发生了,6点开始定时任务又停了。 Spring定时任务为什么会被阻塞呢? 原因: 周一中午,我在进行接口状态监控测试时发现,接口状态查询任务尽然会执行半小时。问题找到了,由于我在接口状态查询任务中没有设置读超时、在接口 网络繁忙时,接口状态查询任务会占用很长的时间,Spring定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行。接口状 态查询任务每5分钟执行一次,假如每次都执行1小时的话,其他任务就会被阻塞。因为Quartz的线程都被接口状态查询任务占用了。其他任务只有等待。 解决方法: 1.将JobDetail的concurrent属性配置为false。不允许任务并发执行。 2.任务执行时间较长时,查找根本问题。 实验: JobOne.java

    Java代码 package  test.job;      import  java.util.Date;      public   class  JobOne {       public   void  execute(){           System.out.println("execute JobOne(" + new  Date()+ ")" );           try  {               Thread.sleep(1000000 );           }catch (InterruptedException ire) {                          }       }   }   package test.job; import java.util.Date; public class JobOne { public void execute(){ System.out.println("execute JobOne("+new Date()+")"); try { Thread.sleep(1000000); }catch(InterruptedException ire) { } } }

    JobTwo.java

    Java代码 package  test.job;      import  java.util.Date;      public   class  JobTwo {       public   void  execute(){           System.out.println("execute JobTwo(" + new  Date()+ ")" );       }      }   package test.job; import java.util.Date; public class JobTwo { public void execute(){ System.out.println("execute JobTwo("+new Date()+")"); } }

    配置文件

    Xml代码 <? xml   version = "1.0"   encoding = "UTF-8" ?>    < beans   xmlns = "http://www.springframework.org/schema/beans"   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"           xmlns:aop = "http://www.springframework.org/schema/aop"   xmlns:tx = "http://www.springframework.org/schema/tx"           xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-      beans-2.0.xsd               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">           <!--===== jobOne =====-->               <!-- job -->               < bean   id = "jobOne"   class = "test.job.JobOne"   >                   </ bean >               <!-- job detail -->               < bean   id = "jobOneDetail"   class = "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >            < property   name = "targetObject"   ref = "jobOne" />            < property   name = "targetMethod"   value = "execute" />            < property   name = "concurrent"   value = "true"   />        </ bean >               <!-- Trigger -->               < bean   id = "jobOneSimpleTrigger"   class = "org.springframework.scheduling.quartz.SimpleTriggerBean" >            < property   name = "jobDetail"   ref = "jobOneDetail"   />            < property   name = "startDelay" > < value > 0 </ value > </ property >            < property   name = "repeatInterval" > < value > 1000 </ value > </ property >        </ bean >               <!--===== jobTwo =====-->               <!-- job -->               < bean   id = "jobTwo"   class = "test.job.JobTwo"   >                   </ bean >               <!-- job detail -->               < bean   id = "jobTwoDetail"   class = "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >            < property   name = "targetObject"   ref = "jobTwo" />            < property   name = "targetMethod"   value = "execute" />            < property   name = "concurrent"   value = "true"   />        </ bean >               <!-- Trigger -->               < bean   id = "jobTwoSimpleTrigger"   class = "org.springframework.scheduling.quartz.SimpleTriggerBean" >            < property   name = "jobDetail"   ref = "jobTwoDetail"   />            < property   name = "startDelay" > < value > 0 </ value > </ property >            < property   name = "repeatInterval" > < value > 1000 </ value > </ property >        </ bean >                      <!--===== Schedule =====-->              <!-- schedule -->               < bean    class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" >            < property   name = "triggers" >                < list >                    < ref   local = "jobOneSimpleTrigger" />                    < ref   local = "jobTwoSimpleTrigger" />                </ list >            </ property >        </ bean >           </ beans >    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring- beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!--===== jobOne =====--> <!-- job --> <bean id="jobOne" class="test.job.JobOne" > </bean> <!-- job detail --> <bean id="jobOneDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="jobOne"/> <property name="targetMethod" value="execute"/> <property name="concurrent" value="true" /> </bean> <!-- Trigger --> <bean id="jobOneSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="jobOneDetail" /> <property name="startDelay"><value>0</value></property> <property name="repeatInterval"><value>1000</value></property> </bean> <!--===== jobTwo =====--> <!-- job --> <bean id="jobTwo" class="test.job.JobTwo" > </bean> <!-- job detail --> <bean id="jobTwoDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="jobTwo"/> <property name="targetMethod" value="execute"/> <property name="concurrent" value="true" /> </bean> <!-- Trigger --> <bean id="jobTwoSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="jobTwoDetail" /> <property name="startDelay"><value>0</value></property> <property name="repeatInterval"><value>1000</value></property> </bean> <!--===== Schedule =====--> <!-- schedule --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="jobOneSimpleTrigger"/> <ref local="jobTwoSimpleTrigger"/> </list> </property> </bean> </beans>

    MAIN类:

    Java代码 package  test.job;      import  org.springframework.context.ApplicationContext;   import  org.springframework.context.support.ClassPathXmlApplicationContext;      public   class  JobTest {       private   ApplicationContext ac;          public  JobTest(ApplicationContext ac) {           this .ac = ac;       }       /**        * @param args        */        public   static   void  main(String[] args) {           JobTest job = new  JobTest( new  ClassPathXmlApplicationContext( "applicationContext.xml" ));                     }      }   package test.job; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class JobTest { private ApplicationContext ac; public JobTest(ApplicationContext ac) { this.ac = ac; } /** * @param args */ public static void main(String[] args) { JobTest job = new JobTest(new ClassPathXmlApplicationContext("applicationContext.xml")); } }

    测试结果: 当jobOne的concurrent为true时: execute JobOne(Thu Jan 24 13:40:22 CST 2008) execute JobTwo(Thu Jan 24 13:40:22 CST 2008) execute JobOne(Thu Jan 24 13:40:22 CST 2008) execute JobTwo(Thu Jan 24 13:40:22 CST 2008) execute JobOne(Thu Jan 24 13:40:23 CST 2008) execute JobTwo(Thu Jan 24 13:40:23 CST 2008) execute JobOne(Thu Jan 24 13:40:24 CST 2008) execute JobTwo(Thu Jan 24 13:40:24 CST 2008) execute JobOne(Thu Jan 24 13:40:25 CST 2008) execute JobTwo(Thu Jan 24 13:40:25 CST 2008) execute JobOne(Thu Jan 24 13:40:26 CST 2008) execute JobTwo(Thu Jan 24 13:40:26 CST 2008) execute JobOne(Thu Jan 24 13:40:27 CST 2008) execute JobTwo(Thu Jan 24 13:40:27 CST 2008) execute JobOne(Thu Jan 24 13:40:28 CST 2008) execute JobTwo(Thu Jan 24 13:40:28 CST 2008) execute JobOne(Thu Jan 24 13:40:29 CST 2008) execute JobTwo(Thu Jan 24 13:40:29 CST 2008) execute JobOne(Thu Jan 24 13:40:31 CST 2008) (JobOne并发执行,到这里所有任务阻塞没有信息输出,可以看出默认有10个线程,都被JobOne占用) 当jobOne的concurrent为false时: execute JobOne(Thu Jan 24 13:43:00 CST 2008) execute JobTwo(Thu Jan 24 13:43:00 CST 2008) execute JobTwo(Thu Jan 24 13:43:00 CST 2008) execute JobTwo(Thu Jan 24 13:43:01 CST 2008) execute JobTwo(Thu Jan 24 13:43:02 CST 2008) execute JobTwo(Thu Jan 24 13:43:03 CST 2008) execute JobTwo(Thu Jan 24 13:43:04 CST 2008) execute JobTwo(Thu Jan 24 13:43:05 CST 2008) execute JobTwo(Thu Jan 24 13:43:06 CST 2008) execute JobTwo(Thu Jan 24 13:43:07 CST 2008) execute JobTwo(Thu Jan 24 13:43:08 CST 2008) execute JobTwo(Thu Jan 24 13:43:09 CST 2008) (JobOne不并发执行,JobTwo不会被阻塞)

    最新回复(0)