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

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

2011-02-15 11:36 561 查看

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不会被阻塞)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: