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

spring quartz使用多线程并发“陷阱”(转)

2015-06-11 14:46 387 查看
定义一个job:ranJob,设置每秒执行一次,设置不允许覆盖并发执行

<bean id="rankJob" class="com.chinacache.www.logstat.job.RankJob" />
<bean id="rankJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="rankJob" />
<property name="targetMethod" value="execute" />
<property name="concurrent" value="false" />
</bean>
<bean id="rankJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="rankJobDetail" />
<!-- 单位 ms,半小时 1800000 ms -->
<property name="repeatInterval" value="1000 />
</bean>


java 代码

public void execute() throws InterruptedException {
System.out.println("Start job");
ExecutorService exec = Executors.newFixedThreadPool(1);

Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread end");
}
});
exec.execute(thread);
exec.shutdown();
while (!exec.isTerminated()) {
// 等待所有子线程结束,才退出主线程
}
System.out.println("end job");
}


打印结果如下:

Start job
thread start
thread end
end job

Start job
thread start
thread end
end job

Start job
thread start
thread end
end job


使用isTerminated()方法等多线程结束后在结束job;多线程任务派发结束后,要使用shutdown()方法顺序关闭线程(等待正在执行任务,不接受新任务)

定义一个job:ranJob,设置每秒执行一次,设置不允许覆盖并发执行

<bean id="rankJob" class="com.chinacache.www.logstat.job.RankJob" />

<bean id="rankJobDetail"

class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="rankJob" />

<property name="targetMethod" value="execute" />

<property name="concurrent" value="<span style="color: #ff0000;"><strong>false</strong></span>" />

</bean>

<bean id="rankJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">

<property name="jobDetail" ref="rankJobDetail" />

<!-- 单位 ms,半小时 1800000 ms -->

<property name="repeatInterval" value="<span style="color: #ff0000;"><strong>1000</strong></span>" />

</bean>

job代码:

System.out.println("Start job");

ExecutorService exec = Executors.newFixedThreadPool(1);

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

System.out.println("thread start");

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("thread end");

}

});

exec.execute(thread);

System.out.println("end job");

程序输出结果:

Start job

end job

<span style="color: #ff0000;"><strong>thread start</strong></span>

Start job

end job

thread start

Start job

end job

thread start

Start job

end job

thread start

<strong><span style="color: #ff0000;">thread end</span></strong>

从结果可以看到,job的并发覆盖配置似乎根本没有生效,原因是:job没有关注多线程执行情况

修改job代码,添加如下代码在job访问最后,线程处理完job才结束,

while (!exec.isTerminated()) {

// 等待所有子线程结束,才退出主线程

}

修改代码后程序结果:

Start job

thread start

thread end

可以看到job始终没有结束,说明ExecutorService始终没有终止,看看文档,加入shutdonw()方法,job所有代码如下:

public void execute() throws InterruptedException {

System.out.println("Start job");

ExecutorService exec = Executors.newFixedThreadPool(1);

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

System.out.println("thread start");

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("thread end");

}

});

exec.execute(thread);

exec.shutdown();

while (!exec.isTerminated()) {

// 等待所有子线程结束,才退出主线程

}

System.out.println("end job");

}

打印结果如下:

Start job

thread start

thread end

end job

Start job

thread start

thread end

end job

Start job

thread start

thread end

end job

OK,至此spring quartz多线程并发问题解决。回顾下,我们要使用isTerminated()方法等多线程结束后在结束job;多线程任务派发结束后,要使用shutdown()方法顺序关闭线程(等待正在执行任务,不接受新任务)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: