java技術(shù)研究

          導(dǎo)航

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

          隨筆分類

          隨筆檔案

          統(tǒng)計

          留言簿(3)

          閱讀排行榜

          評論排行榜

          spring quartz使用多線程并發(fā)“陷阱”(轉(zhuǎn))

          定義一個job:ranJob,設(shè)置每秒執(zhí)行一次,設(shè)置不允許覆蓋并發(fā)執(zhí)行

           

          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");  

           

          程序輸出結(jié)果:

          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>  

           

          從結(jié)果可以看到,job的并發(fā)覆蓋配置似乎根本沒有生效,原因是:job沒有關(guān)注多線程執(zhí)行情況

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

           

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

           

          修改代碼后程序結(jié)果:

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

           

          可以看到j(luò)ob始終沒有結(jié)束,說明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.            // 等待所有子線程結(jié)束,才退出主線程  
          22.        }          
          23.     System.out.println("end job");  
          24. }  

           

          打印結(jié)果如下:

           

          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多線程并發(fā)問題解決。回顧下,我們要使用isTerminated()方法等多線程結(jié)束后在結(jié)束job;多線程任務(wù)派發(fā)結(jié)束后,要使用shutdown()方法順序關(guān)閉線程(等待正在執(zhí)行任務(wù),不接受新任務(wù))

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

          評論

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

          ExecutorService exec = Executors.newFixedThreadPool(1);

          這個地方不能每次都new一個線程池,應(yīng)該當(dāng)作成員變量用。  回復(fù)  更多評論   


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 镇远县| 延津县| 肇庆市| 德安县| 武清区| 佛山市| 民和| 泾阳县| 海伦市| 金堂县| 静乐县| 米林县| 元朗区| 昌宁县| 平凉市| 泾源县| 六盘水市| 达孜县| 腾冲县| 灵宝市| 寻乌县| 东城区| 芒康县| 峡江县| 涿鹿县| 宾川县| 连城县| 保德县| 石首市| 凤山市| 西峡县| 南木林县| 汤原县| 南部县| 乌鲁木齐市| 甘孜县| 甘德县| 三原县| 贵南县| 罗甸县| 韩城市|