java技術研究

          導航

          <2012年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          隨筆分類

          隨筆檔案

          統計

          留言簿(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 小秦 閱讀(8129) 評論(1)  編輯  收藏

          評論

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

          ExecutorService exec = Executors.newFixedThreadPool(1);

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


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


          網站導航:
           
          主站蜘蛛池模板: 任丘市| 保定市| 漳平市| 潮州市| 五寨县| 金阳县| 莱阳市| 陆良县| 南宫市| 大同市| 正蓝旗| 故城县| 柘城县| 固镇县| 嘉定区| 左权县| 班玛县| 四会市| 广丰县| 汽车| 六枝特区| 达日县| 察雅县| 潜山县| 永宁县| 德安县| 图片| 鹤峰县| 都安| 金华市| 花莲市| 巩义市| 镇康县| 静乐县| 鸡东县| 漳浦县| 孝昌县| 无棣县| 兴文县| 那坡县| 靖西县|