Java 計時器

1.Timer and TimerTask:安全

Timer是jdk中提供的一個定時器工具,使用的時候會在主線程以外起一個單獨的線程執行指定的計劃任務,能夠指定執行一次或者反覆執行屢次。jvm

TimerTask是一個實現了Runnable接口的抽象類,表明一個能夠被Timer執行的任務。ide

2. Steps :工具

  (1)繼承TimerTask,注意TimerTask是實現Runnable接口的,所以只要重載run() 方法便可。post

  (2)建立Timer對象,調用schedule()方法。spa

3. Methods:線程

void cancel()code

終止此計時器,丟棄全部當前已安排的任務。對象

int purge()blog

今後計時器的任務隊列中移除全部已取消的任務。

void schedule(TimerTask task, Date time)

安排在指定的時間執行指定的任務。

void schedule(TimerTask task, Date firstTime, long period)

安排指定的任務在指定的時間開始進行重複的固定延遲執行

void schedule(TimerTask task, long delay)

安排在指定延遲後執行指定的任務。

void schedule(TimerTask task, long delay, long period)

安排指定的任務從指定的延遲後開始進行重複的固定延遲執行

void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

安排指定的任務在指定的時間開始進行重複的固定速率執行

void scheduleAtFixedRate(TimerTask task, long delay, long period)

安排指定的任務在指定的延遲後開始進行重複的固定速率執行

注: 時間都是 毫秒 (ms)

schedule VS. scheduleAtFixedRate

這兩個方法都是任務調度方法,他們之間區別是,schedule會保證任務的間隔是按照定義的period參數嚴格執行的,若是某一次調度時間比較長,那麼後面的時間會順延,保證調度間隔都是period,而scheduleAtFixedRate是嚴格按照調度時間來的,若是某次調度時間太長了,那麼會經過縮短間隔的方式保證下一次調度在預約時間執行。舉個栗子:你每一個3秒調度一次,那麼正常就是0,3,6,9s這樣的時間,若是第二次調度花了2s的時間,若是是schedule,就會變成0,3+2,8,11這樣的時間,保證間隔,而scheduleAtFixedRate就會變成0,3+2,6,9,壓縮間隔,保證調度時間。

4: 如何終止Timer線程

  默認狀況下,建立的timer線程會一直執行,主要有下面四種方式來終止timer線程:

  • 調用timer的cancle方法
  • 把timer線程設置成daemon線程,(new Timer(true)建立daemon線程),在jvm裏,若是全部用戶線程結束,那麼守護線程也會被終止,不過這種方法通常不用。
  • 當全部任務執行結束後,刪除對應timer對象的引用,線程也會被終止。
  • 調用System.exit方法終止程序。

5. 總結

  • 每個Timer僅對應惟一一個線程。
  • Timer不保證任務執行的十分精確。
  • Timer類的線程安全的。

Example:

Timer logTimer = new Timer();
        try{
            Set<Property> additionalCompressFields = additionalCompressedLevels.get(timeCompressionLevel);
            Map<String, IPosting> compressedPostings = new HashMap<String, IPosting>();
            final ConcurrentLinkedDeque<Posting> postingsDeque = new ConcurrentLinkedDeque<Posting>();
            postingsDeque.addAll(postings);
            Posting posting = null;
            {
                //Start a timer to print the remaining posting size
                TimerTask task = new TimerTask(){
                    @Override
                    public void run() {
                        if(postingsDeque.size() > 0 ) {
                            LOGGER.log(Level.INFO, ">>>>>> Remainning items to compress [" + postingsDeque.size() + "] <<<<<<<<<");
                        } 
                    }
                    
                };
                logTimer.scheduleAtFixedRate(task, 30000, 30000);
            }
            while((posting = postingsDeque.poll()) != null){
               ...
            }
        }finally{
            logTimer.cancel();
        }

只是個方法一部分,沒有運行結果。

相關文章
相關標籤/搜索