Android Timer和TimerTask

來源:互聯網
上載者:User

標籤:

以下內容根據 The JavaTM Tutorial 和相關API doc翻譯整理,以供日後參考:1.概覽

Timer是一種定時器工具,用來在一個後台線程計劃執行指定任務。它可以計劃執行一個任務一次或反覆多次。
TimerTask一個抽象類別,它的子類代表一個可以被Timer計劃的任務。
簡單的一個常式:

mport java.util.Timer;import java.util.TimerTask;/*** Simple demo that uses java.util.Timer to schedule a task to execute* once 5 seconds have passed.*/public class Reminder {    Timer timer;    public Reminder(int seconds) {        timer = new Timer();        timer.schedule(new RemindTask(), seconds*1000);    }    class RemindTask extends TimerTask {        public void run() {            System.out.println("Time‘s up!");            timer.cancel(); //Terminate the timer thread        }    }    public static void main(String args[]) {        System.out.println("About to schedule task.");        new Reminder(5);        System.out.println("Task scheduled.");    }}

運行這個小例子,你會首先看到:

About to schedule task.

5秒鐘之後你會看到:

Time‘s up!

這個小例子可以說明一些用Timer線程實現和計劃執行一個任務的基礎步驟:

  • 實現自訂的TimerTask的子類,run方法包含要執行的任務代碼,在這個例子裡,這個子類就是RemindTask。
  • 執行個體化Timer類,建立計時器後台線程。
  • 執行個體化任務對象 (new RemindTask()).
  • 制定執行計畫。這裡用schedule方法,第一個參數是TimerTask對象,第二個參數表示開始執行前的延時時間(單位是milliseconds,這裡定義了5000)。還有一種方法可以指定任務的執行時間,如下例,指定任務在11:01 p.m.執行:
 //Get the Date corresponding to 11:01:00 pm today.Calendar calendar = Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY, 23);calendar.set(Calendar.MINUTE, 1);calendar.set(Calendar.SECOND, 0);Date time = calendar.getTime();timer = new Timer();timer.schedule(new RemindTask(), time);
2.終止Timer線程

預設情況下,只要一個程式的timer線程在運行,那麼這個程式就會保持運行。當然,你可以通過以下四種方法終止一個timer線程:

  • 調用timer的cancle方法。你可以從程式的任何地方調用此方法,甚至在一個timer task的run方法裡。
  • 讓timer線程成為一個daemon線程(可以在建立timer時使用new Timer(true)達到這個目地),這樣當程式只有daemon線程的時候,它就會自動終止運行。
  • 當timer相關的所有task執行完畢以後,刪除所有此timer對象的引用(置成null),這樣timer線程也會終止。
  • 調用System.exit方法,使整個程式(所有線程)終止。

Reminder的例子使用了第一種方式。在這裡不能使用第二種方式,因為這裡需要程式保持運行直到timer的任務執行完成,如果設成daemon,那 麼當main線程結束的時候,程式只剩下timer這個daemon線程,於是程式不會等timer線程執行task就終止了。

有些時候,程式的終止與否並不只與timer線程有關。舉個例子,如果我們使用AWT來beep,那麼AWT會自動建立一個非daemon線程來保持程式 的運行。下面的代碼我們對Reminder做了修改,加入了beeping功能,於是我們需要加入System.exit的調用來終止程式。

import java.util.Timer;import java.util.TimerTask;import java.awt.Toolkit;/*** Simple demo that uses java.util.Timer to schedule a task to execute* once 5 seconds have passed.*/public class ReminderBeep {    Toolkit toolkit;    Timer timer;    public ReminderBeep(int seconds) {        toolkit = Toolkit.getDefaultToolkit();        timer = new Timer();        timer.schedule(new RemindTask(), seconds*1000);    }    class RemindTask extends TimerTask {        public void run() {            System.out.println("Time‘s up!");    toolkit.beep();    //timer.cancel(); //Not necessary because we call System.exit    System.exit(0);   //Stops the AWT thread (and everything else)        }    }    public static void main(String args[]) {System.out.println("About to schedule task.");        new ReminderBeep(5);System.out.println("Task scheduled.");    }}
3.反覆執行一個任務

先看一個例子:

public class AnnoyingBeep {    Toolkit toolkit;    Timer timer;    public AnnoyingBeep() {        toolkit = Toolkit.getDefaultToolkit();        timer = new Timer();        timer.schedule(new RemindTask(),               0,        //initial delay               1*1000);  //subsequent rate    }    class RemindTask extends TimerTask {        int numWarningBeeps = 3;        public void run() {            if (numWarningBeeps > 0) {                toolkit.beep();                System.out.println("Beep!");                numWarningBeeps--;            } else {                toolkit.beep();                System.out.println("Time‘s up!");                //timer.cancel(); //Not necessary because we call System.exit                System.exit(0);   //Stops the AWT thread (and everything else)            }        }    }    ...}

執行,你會看到如下輸出:

Task scheduled.
Beep!     
Beep!      //one second after the first beep
Beep!      //one second after the second beep
Time‘s up! //one second after the third beep

這裡使用了三個參數的schedule方法用來指定task每隔一秒執行一次。如下所列為所有Timer類用來制定計劃反覆執行task的方法 :

  • schedule(TimerTask task, long delay, long period)
  • schedule(TimerTask task, Date time, long period)
  • scheduleAtFixedRate(TimerTask task, long delay, long period)
  • scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

 

當計劃反覆執行的任務時,如果你注重任務執行的平滑度,那麼請使用schedule方法,如果你在乎的是任務的執行頻度那麼使用 scheduleAtFixedRate方法。 例如,這裡使用了schedule方法,這就意味著所有beep之間的時間間隔至少為1秒,也就是說,如果有一個beap因為某種原因遲到了(未按計劃執 行),那麼餘下的所有beep都要延時執行。如果我們想讓這個程式正好在3秒以後終止,無論哪一個beep因為什麼原因被延時,那麼我們需要使用 scheduleAtFixedRate方法,這樣當第一個beep遲到時,那麼後面的beep就會以最快的速度緊密執行(最大限度的壓縮間隔時間)。

4.進一步分析schedule和scheduleAtFixedRate

(1)2個參數的schedule在制定任務計劃時, 如果指定的計劃執行時間 scheduledExecutionTime<=systemCurrentTime,則task會被立即執行。 scheduledExecutionTime不會因為某一個task的過度執行而改變。
(2)3個參數的schedule在制定反覆執行一個task的計劃時,每一次執行這個task的計劃執行時間隨著前一次的實際執行時間而變,也就是scheduledExecutionTime(第n+1次)=realExecutionTime(第n次)+periodTime。也就是說如果第n次執行task時,由於某種原因這次執行時間過長,執行完後的systemCurrentTime>=scheduledExecutionTime(第n+1次),則此時不做時隔等待,立即執行第n+1次task,而接下來的第n+2次task的scheduledExecutionTime(第n+2次)就隨著變成了realExecutionTime(第n+1次)+periodTime。說白了,這個方法更注重保持間隔時間的穩定。
(3)3個參數的scheduleAtFixedRate在制定反覆執行一個task的計劃時,每一次執行這個task的計劃執行時間在最初就被定下來了,也就是scheduledExecutionTime(第n次)=firstExecuteTime+n*periodTime;如果第n次執行task時,由於某種原因這次執行時間過長,執行完後的systemCurrentTime>=scheduledExecutionTime(第n+1次),則此時不做period間隔等待,立即執行第n+1次task,而接下來的第n+2次的task的scheduledExecutionTime(第n+2次)依然還是firstExecuteTime+(n+2)*periodTime這在第一次執行task就定下來了。說白了,這個方法更注重保持執行頻率的穩定。

5.一些注意的問題
  • 每一個Timer僅對應唯一一個線程。
  • Timer不保證任務執行的十分精確。
  • Timer類的安全執行緒的。

 

Android Timer和TimerTask

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.