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

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

    <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 代码spring

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,设置每秒执行一次,设置不容许覆盖并发执行ide

  1. <bean id="rankJob" class="com.chinacache.www.logstat.job.RankJob" />  
  2. <bean id="rankJobDetail"  
  3.     class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
  4.     <property name="targetObject" ref="rankJob" />  
  5.     <property name="targetMethod" value="execute" />  
  6.     <property name="concurrent" value="<span style="color: #ff0000;"><strong>false</strong></span>" />  
  7. </bean>  
  8. <bean id="rankJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">  
  9.     <property name="jobDetail" ref="rankJobDetail" />  
  10.     <!-- 单位 ms,半小时 1800000 ms -->  
  11.     <property name="repeatInterval" value="<span style="color: #ff0000;"><strong>1000</strong></span>" />  
  12. </bean>  

 

job代码:spa

  1. System.out.println("Start job");  
  2. ExecutorService exec = Executors.newFixedThreadPool(1);  
  3.   
  4. Thread thread = new Thread(new Runnable() {  
  5.     @Override  
  6.     public void run() {  
  7.         System.out.println("thread start");  
  8.         try {  
  9.             Thread.sleep(3000);  
  10.         } catch (InterruptedException e) {  
  11.             // TODO Auto-generated catch block  
  12.             e.printStackTrace();  
  13.         }  
  14.         System.out.println("thread end");  
  15.     }  
  16. });  
  17. exec.execute(thread);  
  18. System.out.println("end job");  

 

程序输出结果:线程

  1. Start job  
  2. end job  
  3. <span style="color: #ff0000;"><strong>thread start</strong></span>  
  4. Start job  
  5. end job  
  6. thread start  
  7. Start job  
  8. end job  
  9. thread start  
  10. Start job  
  11. end job  
  12. thread start  
  13. <strong><span style="color: #ff0000;">thread end</span></strong>  

 

从结果能够看到,job的并发覆盖配置彷佛根本没有生效,缘由是:job没有关注多线程执行状况code

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

 

  1. while (!exec.isTerminated()) {  
  2.     // 等待全部子线程结束,才退出主线程  
  3. }  

 

修改代码后程序结果:blog

  1. Start job  
  2. thread start  
  3. thread end  

 

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

  1. public void execute() throws InterruptedException {  
  2.     System.out.println("Start job");  
  3.     ExecutorService exec = Executors.newFixedThreadPool(1);  
  4.       
  5.     Thread thread = new Thread(new Runnable() {  
  6.         @Override  
  7.         public void run() {  
  8.             System.out.println("thread start");  
  9.             try {  
  10.                 Thread.sleep(3000);  
  11.             } catch (InterruptedException e) {  
  12.                 // TODO Auto-generated catch block  
  13.                 e.printStackTrace();  
  14.             }  
  15.             System.out.println("thread end");  
  16.         }  
  17.     });  
  18.     exec.execute(thread);  
  19.     exec.shutdown();  
  20.        while (!exec.isTerminated()) {  
  21.            // 等待全部子线程结束,才退出主线程  
  22.        }          
  23.     System.out.println("end job");  
  24. }  

 

打印结果以下:

 

  1. Start job  
  2. thread start  
  3. thread end  
  4. end job  
  5.   
  6. Start job  
  7. thread start  
  8. thread end  
  9. end job  
  10.   
  11. Start job  
  12. thread start  
  13. thread end  
  14. end job  

 

 

OK,至此spring quartz多线程并发问题解决。回顾下,咱们要使用isTerminated()方法等多线程结束后在结束job;多线程任务派发结束后,要使用shutdown()方法顺序关闭线程(等待正在执行任务,不接受新任务)

相关文章
相关标签/搜索