java技術研究

          統計

          留言簿(3)

          閱讀排行榜

          評論排行榜

          spring quartz使用多線程并發“陷阱”(轉)

          定義一個job:ranJob,設置每秒執行一次,設置不允許覆蓋并發執行

           

          Xml代碼  
          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代碼:

          Java代碼  
          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");  

           

          程序輸出結果:

          Java代碼  
          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沒有關注多線程執行情況

          修改job代碼,添加如下代碼在job訪問最后,線程處理完job才結束,

           

          Java代碼  
          1. while (!exec.isTerminated()) {  
          2.     // 等待所有子線程結束,才退出主線程  
          3. }  

           

          修改代碼后程序結果:

          Java代碼  
          1. Start job  
          2. thread start  
          3. thread end  

           

          可以看到job始終沒有結束,說明ExecutorService始終沒有終止,看看文檔,加入shutdonw()方法,job所有代碼如下:

          Java代碼  
          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. }  

           

          打印結果如下:

           

          Java代碼  
          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()方法順序關閉線程(等待正在執行任務,不接受新任務)

          posted on 2012-04-19 14:15 小秦 閱讀(8134) 評論(1)  編輯  收藏

          評論

          # re: spring quartz使用多線程并發“陷阱”(轉) 2013-09-24 11:24 sharkbobo

          ExecutorService exec = Executors.newFixedThreadPool(1);

          這個地方不能每次都new一個線程池,應該當作成員變量用。  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 高邑县| 蒙自县| 武穴市| 昌图县| 塘沽区| 隆昌县| 东海县| 梁河县| 山阳县| 呼伦贝尔市| 中宁县| 洛扎县| 满洲里市| 兖州市| 米易县| 广东省| 恩施市| 浪卡子县| 阿坝县| 新蔡县| 太仆寺旗| 满城县| 舟曲县| 上虞市| 双辽市| 攀枝花市| 巴彦县| 苍溪县| 化隆| 广丰县| 子长县| 宣恩县| 酒泉市| 根河市| 始兴县| 绿春县| 靖边县| 曲水县| 荥经县| 西畴县| 丁青县|