日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

timer定时器_拾遗Timer定时器

發(fā)布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 timer定时器_拾遗Timer定时器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一 Timer ?介紹

在開發(fā)中我們經(jīng)常會遇到一些簡單定時任務(wù)的需求,而不需要量級較重的定時任務(wù)就可以采取java定時器;

java.util.Timer工具類中的Timer 是定時器,但定時任務(wù)寫在java.util.TimerTask 中,由 Timer 執(zhí)行 TimerTask ;

Timer 的本質(zhì)就是線程,構(gòu)造方法如下

public?Timer(String?name)?{
????????thread.setName(name);
????????thread.start();
????}

從源碼角度可知,如果這樣創(chuàng)建定時器非守護線程,即使主線程運行結(jié)束,定時任務(wù)還是會執(zhí)行;如果我們會使用如下的構(gòu)造方式創(chuàng)建定時任務(wù)就是守護線程方式,會隨著主線程的消亡而消亡;

public?Timer(String?name,?boolean?isDaemon)?{
????????thread.setName(name);
????????thread.setDaemon(isDaemon);
????????thread.start();
????}

Timer內(nèi)部維護了一個優(yōu)先隊列,用于順序執(zhí)行TimerTask任務(wù);

private?final?TaskQueue?queue?=?new?TaskQueue();
private?final?TimerThread?thread?=?new?TimerThread(queue);

優(yōu)先隊列的實現(xiàn)就是數(shù)組方式作為平衡二叉堆

private?TimerTask[]?queue?=?new?TimerTask[128];

TimerTask 實現(xiàn)了Runnable 接口,執(zhí)行的任務(wù)動作就是run方法;

public?abstract?class?TimerTask?implements?Runnable?{
?//?....
?????protected?TimerTask()?{
????}

????public?abstract?void?run();
?//....
}

所以「定時器的本質(zhì)就是啟動了一個新的線程執(zhí)行任務(wù),這些任務(wù)都會維護在優(yōu)先隊列里面」

timer的調(diào)度主要方法如下

  • schedule(TimerTask task, long delay) ? 延遲 delay 毫秒執(zhí)行一次
  • schedule(TimerTask task, Date time) 指定時間執(zhí)行一次
  • schedule(TimerTask task, long delay, long period) 延遲delay毫秒以后,每隔period毫秒執(zhí)行一次
  • schedule(TimerTask task, Date firstTime, long period) 從firstTime時刻開始,每隔period毫秒執(zhí)行一次

二 Timer使用示例

如果方式簡單使用Timer去延遲執(zhí)行線程任務(wù),當(dāng)然其它四種方法同理,調(diào)用方式區(qū)別不大;

????public?static?void?main(String[]?args)?{
????????//?創(chuàng)建定時器
????????Timer?timer?=?new?Timer("知識追尋者");
????????//?創(chuàng)建定時器任務(wù);實現(xiàn)run 方法
????????TimerTask?timerTask?=?new?TimerTask()?{
????????????@Override
????????????public?void?run()?{
????????????????System.out.println("線程執(zhí)行了"+?LocalTime.now());
????????????}
????????};
????????System.out.println("程序執(zhí)行時間"+?LocalTime.now());
????????//?啟動定時器
????????timer.schedule(timerTask,5000);
????}

輸出的間隔大約就是5秒

程序執(zhí)行時間?18:47:28.258
線程執(zhí)行了18:47:33.259

三 cancel 方法

TimerTask的cancel () 方法是將自身任務(wù)從任務(wù)隊列中移除

我們先延遲2秒,再每2秒執(zhí)行一次看效果

????public?static?void?main(String[]?args)?{
????????//?創(chuàng)建定時器
????????Timer?timer?=?new?Timer("知識追尋者");
????????//?創(chuàng)建定時器任務(wù);實現(xiàn)run 方法
????????TimerTask?timerTask?=?new?TimerTask()?{
????????????@Override
????????????public?void?run()?{
????????????????System.out.println("線程執(zhí)行了"+?LocalTime.now());
????????????}
????????};
????????System.out.println("程序執(zhí)行時間"+?LocalTime.now());
????????//?啟動定時器
????????timer.schedule(timerTask,2000,2000);
????}

結(jié)果是每2秒會執(zhí)行一次

程序執(zhí)行時間18:59:23.557
線程執(zhí)行了18:59:25.558
線程執(zhí)行了18:59:27.558
線程執(zhí)行了18:59:29.559

啟用cancel方法,后 就只會執(zhí)行一次

????public?static?void?main(String[]?args)?{
????????//?創(chuàng)建定時器
????????Timer?timer?=?new?Timer("知識追尋者");
????????//?創(chuàng)建定時器任務(wù);實現(xiàn)run 方法
????????TimerTask?timerTask?=?new?TimerTask()?{
????????????@Override
????????????public?void?run()?{
????????????????System.out.println("線程執(zhí)行了"+?LocalTime.now());
????????????????//?調(diào)用?cancel方法
????????????????this.cancel();
????????????}
????????};
????????System.out.println("程序執(zhí)行時間"+?LocalTime.now());
????????//?啟動定時器
????????timer.schedule(timerTask,2000,2000);
????}

輸出如下

程序執(zhí)行時間19:02:12.770
線程執(zhí)行了19:02:14.772

Timer的cancel方法是移除所有的任務(wù);

????public?static?void?main(String[]?args)?{
????????//?創(chuàng)建定時器
????????Timer?timer?=?new?Timer("知識追尋者");
????????//?創(chuàng)建定時器任務(wù);實現(xiàn)run 方法
????????TimerTask?timerTask?=?new?TimerTask()?{
????????????@Override
????????????public?void?run()?{
????????????????System.out.println("線程執(zhí)行了"+?LocalTime.now());
????????????}
????????};
????????System.out.println("程序執(zhí)行時間"+?LocalTime.now());
????????timer.cancel();
????????//?啟動定時器
????????timer.schedule(timerTask,2000,2000);
????}

輸出直接報錯

程序執(zhí)行時間:19:34.294
Exception?in?thread?"main"?java.lang.IllegalStateException:?Timer?already?cancelled.
?at?java.util.Timer.sched(Timer.java:397)
?at?java.util.Timer.schedule(Timer.java:248)
?at?com.youku1327.base.timer.TimerAbsolute.main(TimerAbsolute.java:28)

四 scheduleAtFixedRate

schedule 與 scheduleAtFixedRate ?方法的區(qū)別如下:

schedule 方法如果執(zhí)行任務(wù)的時間沒有被延遲,下一次執(zhí)行任務(wù)時間參考的是上一次任務(wù)執(zhí)行的開始時間

scheduleAtFixedRate ?方法如果執(zhí)行任務(wù)的時間沒有被延遲,下一次執(zhí)行任務(wù)時間參考的是上一次任務(wù)執(zhí)行的結(jié)束時間

五 Timer缺點

  • Timer 對調(diào)度的支持是基于絕對時間的,而不是相對時間,所以它對系統(tǒng)時間的改變非常敏感。
  • Timer 線程是不會捕獲異常的,如果 TimerTask 拋出的了未檢查異常則會導(dǎo)致 Timer 線程終止。

總結(jié)

以上是生活随笔為你收集整理的timer定时器_拾遗Timer定时器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。