timer 和 ScheduledThreadExecutor定時

來源:互聯網
上載者:User

 java.util.Timer計時器有管理工作順延強制("如1000ms後執行任務")以及周期性執行("如每500ms執行一次該任務")。但是,Timer存在一些缺陷,因此你應該考慮使用ScheduledThreadPoolExecutor作為代替品,Timer對調度的支援是基於絕對時間,而不是相對時間的,由此任務對系統時鐘的改變是敏感的;ScheduledThreadExecutor只支援相對時間。

    Timer的另一個問題在於,如果TimerTask拋出未檢查的異常,Timer將會產生無法預料的行為。Timer線程並不捕獲異常,所以TimerTask拋出的未檢查的異常會終止timer線程。這種情況下,Timer也不會再重新恢複線程的執行了;它錯誤的認為整個Timer都被取消了。此時,已經被安排但尚未執行的TimerTask永遠不會再執行了,新的任務也不能被調度了。

  1. package com.bill99.test;   
  2.   
  3. import java.util.Timer;   
  4. import java.util.TimerTask;   
  5.   
  6. public class TimerTest {
      
  7.     private Timer timer = new Timer();
      
  8.     //啟動計時器  
  9.     public void lanuchTimer(){
      
  10.         timer.schedule(new TimerTask(){   
  11.             public void run() {
      
  12.                 throw new RuntimeException();
      
  13.             }   
  14.         }, 1000*3, 500);
      
  15.     }   
  16.     //向計時器添加一個任務  
  17.     public void addOneTask(){
      
  18.         timer.schedule(new TimerTask(){   
  19.             public void run(){
      
  20.                 System.out.println("hello world");   
  21.             }   
  22.         }, 1000*1,1000*5);
      
  23.     }   
  24.        
  25.     public static void main(String[] args) throws Exception {
      
  26.         TimerTest test = new TimerTest();   
  27.         test.lanuchTimer();   
  28.         Thread.sleep(1000*5);//5秒鐘之後添加一個新任務  
  29.         test.addOneTask();   
  30.     }   
  31. }  
  32.  

  33. 運行該程式,Timer會拋出一個RumtimeException和java.lang.IllegalStateException:Timer already cancelled.

    常言道,真是禍不單行,Timer還將它的問題傳染給下一個倒黴的調用者,這個調用者原本試圖提交一個TimerTask的,你可能希望程式會一直運行下去,然而實際情況如程式所示5秒鐘後就中止了,還伴隨著一個異常,異常的訊息是"Timer already cancelled"。ScheduledThreadPoolExector妥善地處理了這個異常的任務,所以說在java5.0或更高的JDK中,幾乎沒有理由再使用Timer了。

     用ScheduledThreadPoolExector改進後的例子

  34. package com.bill99.test;   
  35.   
  36. import java.util.concurrent.Executors;   
  37. import java.util.concurrent.ScheduledExecutorService;   
  38. import java.util.concurrent.TimeUnit;   
  39.   
  40. public class ScheduledExecutorTest {
      
  41.     //線程池能按時間計劃來執行任務,允許使用者設定計劃執行任務的時間,int類型的參數是設定  
  42.     //線程池中線程的最小數目。當任務較多時,線程池可能會自動建立更多的背景工作執行緒來執行任務  
  43.     public ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(1);
      
  44.     //啟動計時器  
  45.     public void lanuchTimer(){
      
  46.         Runnable task = new Runnable() {   
  47.             public void run() {
      
  48.                 throw new RuntimeException();
      
  49.             }   
  50.         };   
  51.         scheduExec.scheduleWithFixedDelay(task, 1000*5, 1000*10, TimeUnit.MILLISECONDS);
      
  52.     }   
  53.     //添加新任務  
  54.     public void addOneTask(){
      
  55.         Runnable task = new Runnable() {   
  56.             public void run() {
      
  57.                 System.out.println("welcome to china");   
  58.             }   
  59.         };   
  60.         scheduExec.scheduleWithFixedDelay(task, 1000*1, 1000, TimeUnit.MILLISECONDS);
      
  61.     }   
  62.        
  63.     public static void main(String[] args) throws Exception {
      
  64.         ScheduledExecutorTest test = new ScheduledExecutorTest();   
  65.         test.lanuchTimer();   
  66.         Thread.sleep(1000*5);//5秒鐘之後添加新任務  
  67.         test.addOneTask();   
  68.     }   
  69. ScheduledExecutorService介面
    在ExecutorService的基礎上,ScheduledExecutorService提供了按時間安排執行任務的功能,它提供的方法主要有:
    schedule(task,initDelay):安排所提交的Callable或Runnable任務在initDelay指定的時間後執行。
    scheduleAtFixedRate():安排所提交的Runnable任務按指定的間隔重複執行
    scheduleWithFixedDelay():安排所提交的Runnable任務在每次執行完後,等待delay所指定的時間後重複執行。
    代碼:ScheduleExecutorService的例子
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledFuture;
    import java.util.concurrent.TimeUnit;

    public class ScheduledExecutorServiceTest
    {
           public static void main(String[] args) throws InterruptedException,ExecutionException
           {
                  //*1
                   ScheduledExecutorService service=Executors.newScheduledThreadPool(2);
                   //*2
                   Runnable task1=new Runnable()
                   {
                        public void run()
                        {
                           System.out.println("Taskrepeating.");
                        }
                   };
                   //*3
                   final ScheduledFuture future1=service.scheduleAtFixedRate(task1,0,1,TimeUnit.SECONDS);
                   //*4
                   ScheduledFuture future2=service.schedule(new Callable()
                 {
                        public String call()
                        {
                                future1.cancel(true);
                                return "taskcancelled!";
                        }
                   },10,TimeUnit.SECONDS);
                   System.out.println(future2.get());
        //*5
        service.shutdown();
       }
    }

    這個例子有兩個任務,第一個任務每隔一秒列印一句“Taskrepeating”,第二個任務在5秒鐘後取消第一個任務。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.