spring quartz使用多線程并發(fā)“陷阱”(轉(zhuǎn))
定義一個job:ranJob,設(shè)置每秒執(zhí)行一次,設(shè)置不允許覆蓋并發(fā)執(zhí)行
Xml代碼
- <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代碼:
Java代碼
- 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");
程序輸出結(jié)果:
Java代碼
- 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>
從結(jié)果可以看到,job的并發(fā)覆蓋配置似乎根本沒有生效,原因是:job沒有關(guān)注多線程執(zhí)行情況
修改job代碼,添加如下代碼在job訪問最后,線程處理完job才結(jié)束,
Java代碼
- while (!exec.isTerminated()) {
- // 等待所有子線程結(jié)束,才退出主線程
- }
修改代碼后程序結(jié)果:
Java代碼
- Start job
- thread start
- thread end
可以看到j(luò)ob始終沒有結(jié)束,說明ExecutorService始終沒有終止,看看文檔,加入shutdonw()方法,job所有代碼如下:
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()) {
- // 等待所有子線程結(jié)束,才退出主線程
- }
- System.out.println("end job");
- }
打印結(jié)果如下:
Java代碼
- 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多線程并發(fā)問題解決。回顧下,我們要使用isTerminated()方法等多線程結(jié)束后在結(jié)束job;多線程任務(wù)派發(fā)結(jié)束后,要使用shutdown()方法順序關(guān)閉線程(等待正在執(zhí)行任務(wù),不接受新任務(wù))