免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Java 并發(fā)專題 : Timer的缺陷 用ScheduledExecutorService替代

繼續(xù)并發(fā),上篇博客對于ScheduledThreadPoolExecutor沒有進行介紹,說過會和Timer一直單獨寫一篇Blog.

1、Timer管理延時任務(wù)的缺陷

a、以前在項目中也經(jīng)常使用定時器,比如每隔一段時間清理項目中的一些垃圾文件,每個一段時間進行數(shù)據(jù)清洗;然而Timer是存在一些缺陷的,因為Timer在執(zhí)行定時任務(wù)時只會創(chuàng)建一個線程,所以如果存在多個任務(wù),且任務(wù)時間過長,超過了兩個任務(wù)的間隔時間,會發(fā)生一些缺陷:下面看例子:

Timer的源碼:

  1. public class Timer {  
  2.     /** 
  3.      * The timer task queue.  This data structure is shared with the timer 
  4.      * thread.  The timer produces tasks, via its various schedule calls, 
  5.      * and the timer thread consumes, executing timer tasks as appropriate, 
  6.      * and removing them from the queue when they're obsolete. 
  7.      */  
  8.     private TaskQueue queue = new TaskQueue();  
  9.   
  10.     /** 
  11.      * The timer thread. 
  12.      */  
  13.     private TimerThread thread = new TimerThread(queue);  

TimerThread是Thread的子類,可以看出內(nèi)部只有一個線程。下面看個例子:

  1. package com.zhy.concurrency.timer;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. public class TimerTest  
  7. {  
  8.     private static long start;  
  9.   
  10.     public static void main(String[] args) throws Exception  
  11.     {  
  12.   
  13.         TimerTask task1 = new TimerTask()  
  14.         {  
  15.             @Override  
  16.             public void run()  
  17.             {  
  18.   
  19.                 System.out.println("task1 invoked ! "  
  20.                         + (System.currentTimeMillis() - start));  
  21.                 try  
  22.                 {  
  23.                     Thread.sleep(3000);  
  24.                 } catch (InterruptedException e)  
  25.                 {  
  26.                     e.printStackTrace();  
  27.                 }  
  28.   
  29.             }  
  30.         };  
  31.         TimerTask task2 = new TimerTask()  
  32.         {  
  33.             @Override  
  34.             public void run()  
  35.             {  
  36.                 System.out.println("task2 invoked ! "  
  37.                         + (System.currentTimeMillis() - start));  
  38.             }  
  39.         };  
  40.         Timer timer = new Timer();  
  41.         start = System.currentTimeMillis();  
  42.         timer.schedule(task1, 1000);  
  43.         timer.schedule(task2, 3000);  
  44.   
  45.     }  
  46. }  

定義了兩個任務(wù),預(yù)計是第一個任務(wù)1s后執(zhí)行,第二個任務(wù)3s后執(zhí)行,但是看運行結(jié)果:
  1. task1 invoked ! 1000  
  2. task2 invoked ! 4000  
task2實際上是4后才執(zhí)行,正因為Timer內(nèi)部是一個線程,而任務(wù)1所需的時間超過了兩個任務(wù)間的間隔導(dǎo)致。下面使用ScheduledThreadPool解決這個問題:

  1. package com.zhy.concurrency.timer;  
  2.   
  3. import java.util.TimerTask;  
  4. import java.util.concurrent.Executors;  
  5. import java.util.concurrent.ScheduledExecutorService;  
  6. import java.util.concurrent.TimeUnit;  
  7.   
  8. public class ScheduledThreadPoolExecutorTest  
  9. {  
  10.     private static long start;  
  11.   
  12.     public static void main(String[] args)  
  13.     {  
  14.         /** 
  15.          * 使用工廠方法初始化一個ScheduledThreadPool 
  16.          */  
  17.         ScheduledExecutorService newScheduledThreadPool = Executors  
  18.                 .newScheduledThreadPool(2);  
  19.           
  20.         TimerTask task1 = new TimerTask()  
  21.         {  
  22.             @Override  
  23.             public void run()  
  24.             {  
  25.                 try  
  26.                 {  
  27.   
  28.                     System.out.println("task1 invoked ! "  
  29.                             + (System.currentTimeMillis() - start));  
  30.                     Thread.sleep(3000);  
  31.                 } catch (Exception e)  
  32.                 {  
  33.                     e.printStackTrace();  
  34.                 }  
  35.   
  36.             }  
  37.         };  
  38.   
  39.         TimerTask task2 = new TimerTask()  
  40.         {  
  41.             @Override  
  42.             public void run()  
  43.             {  
  44.                 System.out.println("task2 invoked ! "  
  45.                         + (System.currentTimeMillis() - start));  
  46.             }  
  47.         };  
  48.         start = System.currentTimeMillis();  
  49.         newScheduledThreadPool.schedule(task1, 1000, TimeUnit.MILLISECONDS);  
  50.         newScheduledThreadPool.schedule(task2, 3000, TimeUnit.MILLISECONDS);  
  51.     }  
  52. }  

輸出結(jié)果:

  1. task1 invoked ! 1001  
  2. task2 invoked ! 3001  
符合我們的預(yù)期結(jié)果。因為ScheduledThreadPool內(nèi)部是個線程池,所以可以支持多個任務(wù)并發(fā)執(zhí)行。

2、Timer當任務(wù)拋出異常時的缺陷

如果TimerTask拋出RuntimeException,Timer會停止所有任務(wù)的運行:

  1. package com.zhy.concurrency.timer;  
  2.   
  3. import java.util.Date;  
  4. import java.util.Timer;  
  5. import java.util.TimerTask;  
  6.   
  7.   
  8. public class ScheduledThreadPoolDemo01  
  9. {  
  10.   
  11.   
  12.     public static void main(String[] args) throws InterruptedException  
  13.     {  
  14.   
  15.         final TimerTask task1 = new TimerTask()  
  16.         {  
  17.   
  18.             @Override  
  19.             public void run()  
  20.             {  
  21.                 throw new RuntimeException();  
  22.             }  
  23.         };  
  24.   
  25.         final TimerTask task2 = new TimerTask()  
  26.         {  
  27.   
  28.             @Override  
  29.             public void run()  
  30.             {  
  31.                 System.out.println("task2 invoked!");  
  32.             }  
  33.         };  
  34.           
  35.         Timer timer = new Timer();  
  36.         timer.schedule(task1, 100);  
  37.         timer.scheduleAtFixedRate(task2, new Date(), 1000);  
  38.           
  39.           
  40.   
  41.     }  
  42. }  

上面有兩個任務(wù),任務(wù)1拋出一個運行時的異常,任務(wù)2周期性的執(zhí)行某個操作,輸出結(jié)果:

  1. task2 invoked!  
  2. Exception in thread "Timer-0" java.lang.RuntimeException  
  3.     at com.zhy.concurrency.timer.ScheduledThreadPoolDemo01$1.run(ScheduledThreadPoolDemo01.java:24)  
  4.     at java.util.TimerThread.mainLoop(Timer.java:512)  
  5.     at java.util.TimerThread.run(Timer.java:462)  

由于任務(wù)1的一次,任務(wù)2也停止運行了。。。下面使用ScheduledExecutorService解決這個問題:

  1. package com.zhy.concurrency.timer;  
  2.   
  3. import java.util.Date;  
  4. import java.util.Timer;  
  5. import java.util.TimerTask;  
  6. import java.util.concurrent.Executors;  
  7. import java.util.concurrent.ScheduledExecutorService;  
  8. import java.util.concurrent.TimeUnit;  
  9.   
  10.   
  11. public class ScheduledThreadPoolDemo01  
  12. {  
  13.   
  14.   
  15.     public static void main(String[] args) throws InterruptedException  
  16.     {  
  17.   
  18.         final TimerTask task1 = new TimerTask()  
  19.         {  
  20.   
  21.             @Override  
  22.             public void run()  
  23.             {  
  24.                 throw new RuntimeException();  
  25.             }  
  26.         };  
  27.   
  28.         final TimerTask task2 = new TimerTask()  
  29.         {  
  30.   
  31.             @Override  
  32.             public void run()  
  33.             {  
  34.                 System.out.println("task2 invoked!");  
  35.             }  
  36.         };  
  37.           
  38.           
  39.           
  40.         ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);  
  41.         pool.schedule(task1, 100, TimeUnit.MILLISECONDS);  
  42.         pool.scheduleAtFixedRate(task2, 0 , 1000, TimeUnit.MILLISECONDS);  
  43.   
  44.     }  
  45. }  

代碼基本一致,但是ScheduledExecutorService可以保證,task1出現(xiàn)異常時,不影響task2的運行:

  1. task2 invoked!  
  2. task2 invoked!  
  3. task2 invoked!  
  4. task2 invoked!  
  5. task2 invoked!<span style="font-family: Arial, Helvetica, sans-serif;">...</span>  

3、Timer執(zhí)行周期任務(wù)時依賴系統(tǒng)時間

Timer執(zhí)行周期任務(wù)時依賴系統(tǒng)時間,如果當前系統(tǒng)時間發(fā)生變化會出現(xiàn)一些執(zhí)行上的變化,ScheduledExecutorService基于時間的延遲,不會由于系統(tǒng)時間的改變發(fā)生執(zhí)行變化。


上述,基本說明了在以后的開發(fā)中盡可能使用ScheduledExecutorService(JDK1.5以后)替代Timer。


好了,如果博客中存在錯誤,請留言指出~


 



本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java實現(xiàn)定時任務(wù)的三種方法
Java實現(xiàn)簡單定時任務(wù)
高并發(fā)之——ScheduledThreadPoolExecutor與Timer的區(qū)別和簡單示例
不用任何框架,Java 就能實現(xiàn)定時任務(wù)的 3 種方法!
java定時器的使用(Timer)
Java定時任務(wù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服