java.util.Timer類似於鬧鐘定時做任務

來源:互聯網
上載者:User

標籤:

在web中實現任務計劃,相當於實現鬧鐘的功能,要完成2個步驟:

1、定時器的設定;

2.對這個定時器的啟動運行和停止進行即時監聽

java.util.Timer定時器,實際上是個線程,定時調度所擁有的TimerTasks

一個TimerTask實際上就是一個擁有run方法的類,需要定時執行的代碼放到run方法體內,TimerTask一般是以匿名類方式建立。

Timer是一種線程設施,用於安排以後在後台線程執行的任務,可安排任務執行一次,或者定期重複執行,可以看成一個定時器,可調度TimerTask,TimerTask是一個抽象類別,實現了Runnable介面,所以具備多線程的能力。

Timer類使用java.util.TaskQueue在指定時間間隔新增工作,在任務時刻只能有一個線程執行TimerTask。

Timer類使用對象的wait和notify方法調度任務,Timer對象將持續將任務添加到隊列,一旦有任務結束,它就會通知隊列,並且另外一個線程將啟動執行。

Timer是JDK中定時調度類,主要是來定時觸發任務:

Timer是調度控制器,TimerTask是可調度任務

2.原理:

     其基本處理模型是單線程調度的任務隊列模型,Timer不停地接受調度任務,所有任務接受Timer調度後加入TaskQueue,TimerThread不停地去TaskQueue中取任務來執行.

 

 

     從圖上不難看出,這就是生產者--消費者模型的一種特例:多生產者,單消費者模型。

     此種訊息佇列實現方式在瀏覽器中的編程模型中也有類似的實現,javascript中的定時執行函數setTimeout(expression,milliseconds)也是基於此種原理實現的。

     此種方式的不足之處為當某個任務執行時間較長,以致於超過了TaskQueue中下一個任務開始執行的時間,會影響整個任務執行的即時性。為了提高即時性,可以採用多個消費者一起消費來提高處理效率,避免此類問題的實現。

 Timer裡面有4個schedule重載函數,而且還有兩個scheduleAtFixedRate:
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
安排指定的任務在指定的時間開始進行重複的固定速率執行。
void scheduleAtFixedRate(TimerTask task, long delay, long period)
安排指定的任務在指定的延遲後開始進行重複的固定速率執行。
使用scheduleAtFixedRate的話,Timer會盡量的讓任務在一個固定的頻率下運行。例如:在上面的例子中,讓secondTask在1秒鐘後,每3秒鐘執行一次,但是因為java不是即時的,所以,我們在上個程式中表達的原義並不能夠嚴格執行,例如有時可能資源調度緊張4秒以後才執行下一次,有時候又3.5秒執行。如果我們調用的是scheduleAtFixedRate,那麼Timer會盡量讓你的secondTask執行的頻率保持在3秒一次。運行上面的程式,假設使用的是scheduleAtFixedRate,那麼下面的情境就是可能的:1秒鐘後,secondTask執行一次,因為系統繁忙,之後的3.5秒後secondTask才得以執行第二次,然後Timer記下了這個延遲,並嘗試在下一個任務的時候彌補這個延遲,那麼2.5秒後,secondTask將執行的三次。“以固定的頻率而不是固定的延遲時間去執行一個任務”就是這個意思。
Timer終止的問題:
預設情況下,只要一個程式的timer線程在運行,那麼這個程式就會保持運行。可以通過以下3種方法終止一個timer線程:
(1)調用timer的cancle方法。你可以從程式的任何地方調用此方法,甚至在一個timer task的run方法裡;
(2)讓timer線程成為一個daemon線程(可以在建立timer時使用new Timer(true)達到這個目地),這樣當程式只有daemon線程的時候,它就會自動終止運行;
(3)調用System.exit方法,使整個程式(所有線程)終止。
TimerTask也有cancel方法。
上面所說的“只要一個程式的timer線程在運行,那麼這個程式就會保持運行”。那麼反過來,如果Timer裡的所有TimerTask都執行完了,整個程式會退出嗎,經測試答案是否定的,例如上面的測試代碼,如果只加第一個TimerTask在Timer中執行:
timer.schedule(new MyTask(1), 5000);// 5秒後啟動任務
那麼5秒以後,其實整個程式還是沒有退出,Timer會等待記憶體回收的時候被回收掉然後程式會得以退出,但是多長時間呢?在TimerTask的run函數執行完以後加上System.gc();就可以了。

代碼如下:

package test;

import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {

 /**
  * @param args
  */
 public static void main(String[] args)throws java.io.IOException {
  
        TimerTask task=new TimerTask(){

   @Override
   public void run() {
    System.out.println("hello");
    
   }
         
        };
        Timer timer=new Timer();
        timer.schedule(task, 0,5000);  //0標識要延遲的時間,5000指毫秒
 }

}

是 TimerTask 類,在包:import java.util.TimerTask .使用者要繼承該類,並實現 public void run() 方法,將所要啟動並執行任務封裝其run方法中。因為 TimerTask 類實現了 Runnable 介面。

  1. Timer類:設定定時器的參數,包括起始時間、間隔時間、時延時間,詳情見schedule方法。
  2. 注意點:同一個TimerTask對象不能兩次加入到Timer中執行,若你有多個任務要執行,需要聲明多個TimerTask的執行個體。

第二個參數"0"的意思是:(0就表示無延遲)
當你調用該方法後,該方法必然會調用 TimerTask 類 TimerTask 類 中的 run() 方法,這個參數就是這兩者之間時間的差值,也就是說,使用者調用 schedule() 方法後,要等待這麼長的時間才可以第一次執行 run() 方法。

第三個參數"60*60*1000"的意思就是:
(單位是毫秒60*60*1000為一小時)
(單位是毫秒3*60*1000為三分鐘)
第一次調用之後,從第二次開始每隔多長的時間調用一次 run() 方法。

 

java.util.Timer類似於鬧鐘定時做任務

聯繫我們

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