1.Timer and TimerTask:
Timer是jdk中提供的一個定時器工具,使用的時候會在主線程之外起一個單獨的線程執行指定的計划任務,可以指定執行一次或者反復執行多次。
TimerTask是一個實現了Runnable接口的抽象類,代表一個可以被Timer執行的任務。
2. Steps :
(1)繼承TimerTask,注意TimerTask是實現Runnable接口的,因此只要重載run() 方法即可。
(2)創建Timer對象,調用schedule()方法。
3. Methods:
void cancel()
終止此計時器,丟棄所有當前已安排的任務。
int purge()
從此計時器的任務隊列中移除所有已取消的任務。
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(); }
只是個方法一部分,沒有運行結果。