您的位置:首页 > 编程语言 > Java开发

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

2015-04-02 14:10 316 查看
周日,公司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) {

20000
}

}

}

[java] view
plaincopy

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()+ ")" );

}

}

[java] view
plaincopy

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] view
plaincopy

<?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" ));

}

}

[java] view
plaincopy

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不会被阻塞)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: