一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Timer和TimerTask詳解

 KILLKISS 2010-05-12

1.概覽
Timer是一種定時器工具,用來在一個后臺線程計(jì)劃執(zhí)行指定任務(wù)。它可以計(jì)劃執(zhí)行一個任務(wù)一次或反復(fù)多次。
TimerTask一個抽象類,它的子類代表一個可以被Timer計(jì)劃的任務(wù)。

簡單的一個例程:


import 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.");
    }
}

運(yùn)行這個小例子,你會首先看到:

About to schedule task.

5秒鐘之后你會看到:

Time's up!

這個小例子可以說明一些用Timer線程實(shí)現(xiàn)和計(jì)劃執(zhí)行一個任務(wù)的基礎(chǔ)步驟:

實(shí)現(xiàn)自定義的TimerTask的子類,run方法包含要執(zhí)行的任務(wù)代碼,在這個例子里,這個子類就是RemindTask。
實(shí)例化Timer類,創(chuàng)建計(jì)時器后臺線程。
實(shí)例化任務(wù)對象 (new RemindTask()).
制定執(zhí)行計(jì)劃。這里用schedule方法,第一個參數(shù)是TimerTask對象,第二個參數(shù)表示開始執(zhí)行前的延時時間(單位是milliseconds,這里定義了5000)。還有一種方法可以指定任務(wù)的執(zhí)行時間,如下例,指定任務(wù)在11:01 p.m.執(zhí)行:
 //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線程
默認(rèn)情況下,只要一個程序的timer線程在運(yùn)行,那么這個程序就會保持運(yùn)行。當(dāng)然,你可以通過以下四種方法終止一個timer線程:


調(diào)用timer的cancle方法。你可以從程序的任何地方調(diào)用此方法,甚至在一個timer task的run方法里。
讓timer線程成為一個daemon線程(可以在創(chuàng)建timer時使用new Timer(true)達(dá)到這個目地),這樣當(dāng)程序只有daemon線程的時候,它就會自動終止運(yùn)行。
當(dāng)timer相關(guān)的所有task執(zhí)行完畢以后,刪除所有此timer對象的引用(置成null),這樣timer線程也會終止。
調(diào)用System.exit方法,使整個程序(所有線程)終止。
Reminder的例子使用了第一種方式。在這里不能使用第二種方式,因?yàn)檫@里需要程序保持運(yùn)行直到timer的任務(wù)執(zhí)行完成,如果設(shè)成daemon,那么當(dāng)main線程結(jié)束的時候,程序只剩下timer這個daemon線程,于是程序不會等timer線程執(zhí)行task就終止了。

有些時候,程序的終止與否并不只與timer線程有關(guān)。舉個例子,如果我們使用AWT來beep,那么AWT會自動創(chuàng)建一個非daemon線程來保持程序的運(yùn)行。下面的代碼我們對Reminder做了修改,加入了beeping功能,于是我們需要加入System.exit的調(diào)用來終止程序。

 


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.反復(fù)執(zhí)行一個任務(wù)

先看一個例子:

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)
            }
        }
    }
    ...
}

執(zhí)行,你會看到如下輸出:

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

這里使用了三個參數(shù)的schedule方法用來指定task每隔一秒執(zhí)行一次。如下所列為所有Timer類用來制定計(jì)劃反復(fù)執(zhí)行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)
當(dāng)計(jì)劃反復(fù)執(zhí)行的任務(wù)時,如果你注重任務(wù)執(zhí)行的平滑度,那么請使用schedule方法,如果你在乎的是任務(wù)的執(zhí)行頻度那么使用scheduleAtFixedRate方法。 例如,這里使用了schedule方法,這就意味著所有beep之間的時間間隔至少為1秒,也就是說,如果有一個beap因?yàn)槟撤N原因遲到了(未按計(jì)劃執(zhí)行),那么余下的所有beep都要延時執(zhí)行。如果我們想讓這個程序正好在3秒以后終止,無論哪一個beep因?yàn)槭裁丛虮谎訒r,那么我們需要使用scheduleAtFixedRate方法,這樣當(dāng)?shù)谝粋€beep遲到時,那么后面的beep就會以最快的速度緊密執(zhí)行(最大限度的壓縮間隔時間)。

4.進(jìn)一步分析schedule和scheduleAtFixedRate


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

 

5.一些注意的問題
每一個Timer僅對應(yīng)唯一一個線程。
Timer不保證任務(wù)執(zhí)行的十分精確。
Timer類的線程安全的。

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/ahxu/archive/2005/01/12/249610.aspx

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲国产性生活高潮免费视频| 亚洲中文字幕在线观看黑人| 91欧美亚洲视频在线| 色丁香一区二区黑人巨大| 日本少妇aa特黄大片| 午夜福利国产精品不卡| 国产午夜精品久久福利| av中文字幕一区二区三区在线| 成人欧美精品一区二区三区| 午夜午夜精品一区二区| 久久少妇诱惑免费视频| 久久精品视频就在久久| 国产精品免费自拍视频| 国产二级一级内射视频播放| 国产熟女高清一区二区| 日韩专区欧美中文字幕| 美国欧洲日本韩国二本道| 亚洲日本久久国产精品久久| 天堂网中文字幕在线视频| 欧美日韩一区二区午夜| 视频在线播放你懂的一区| 日本男人女人干逼视频| 亚洲av在线视频一区| 三级理论午夜福利在线看| 丝袜av一区二区三区四区五区| 亚洲人午夜精品射精日韩| 欧美精品久久男人的天堂| 日本美国三级黄色aa| 中文字幕日韩精品人一妻| 日本一区二区三区黄色| 少妇视频一区二区三区| 不卡中文字幕在线免费看| 日韩偷拍精品一区二区三区| 国产精品内射婷婷一级二级| 黄色国产精品一区二区三区| 乱女午夜精品一区二区三区| 亚洲国产欧美久久精品| 国产成人精品一区在线观看| 国产剧情欧美日韩中文在线| 日本东京热视频一区二区三区| 2019年国产最新视频|