spring quartz使用多线程并发“陷阱”(转)
2015-06-11 14:46
387 查看
定义一个job:ranJob,设置每秒执行一次,设置不允许覆盖并发执行
java 代码
打印结果如下:
使用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()方法顺序关闭线程(等待正在执行任务,不接受新任务)
<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()方法顺序关闭线程(等待正在执行任务,不接受新任务)
相关文章推荐
- 解决myeclipse部署web项目时报错
- java.lang.NoClassDefFoundError:org/bouncycastle/jce/provider/BouncyCastl
- Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法
- Java项目命名规范
- java 跳出多层循环
- Java数组求平均数且输出大于平均数的数字
- java生成密码,包含大小写和数字
- Spring集成Mina
- Collection 和Collections的区别|、String的getBytes方法
- 关于JAVA 并发类的Executor误用导致的线程数量异常
- java 堆 栈 方法区的简单分析
- Java中的泛型方法
- java 多线程(threadlocal)
- java 多线程(ReadWriteLock)
- Java读取、创建xml(通过dom方式)
- java 多线程(wait/notify/notifyall)
- java 多线程(synchronized)
- java 多线程(daemon)
- SpringMVC-------->Controller获得上传文件的绝对路径
- SpringMVC整合Shiro