Java時(shí)間類(lèi)庫(kù)Timer的使用方法與實(shí)例詳解
使用 Java 來(lái)調(diào)度定時(shí)任務(wù)時(shí),我們經(jīng)常會(huì)使用 Timer 類(lèi)搞定。Timer 簡(jiǎn)單易用,在一些業(yè)務(wù)場(chǎng)景下用來(lái)實(shí)現(xiàn)簡(jiǎn)單定時(shí)調(diào)度。
Jave時(shí)間類(lèi)庫(kù)Timer簡(jiǎn)單使用
- 創(chuàng)建Timer對(duì)象
- 編寫(xiě) 自己的 task 類(lèi),該類(lèi)集成 TimerTask,重寫(xiě) run 方法,把要定時(shí)執(zhí)行的邏輯寫(xiě)在里面
- 使用 Timer 執(zhí)行 TimerTask
// 5秒后開(kāi)始執(zhí)行,每秒執(zhí)行一次 Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("hello world"); } }, 50000 , 1000);
Timer 里面的一些常用方法
經(jīng)過(guò)delay(ms)后開(kāi)始進(jìn)行調(diào)度,僅僅調(diào)度一次。
public void schedule(TimerTask task, long delay)
在指定的時(shí)間點(diǎn)time上調(diào)度一次
public void schedule(TimerTask task, Date time)
在delay(ms)后開(kāi)始調(diào)度,每次調(diào)度完后,最少等待period(ms)后才開(kāi)始調(diào)度
public void schedule(TimerTask task, long delay, long period)
在到了指定時(shí)間后開(kāi)始調(diào)度,每次調(diào)度完后,最少等待period(ms)后才開(kāi)始調(diào)度。
public void schedule(TimerTask task, Date firstTime, long period)
在delay(ms)后開(kāi)始調(diào)度,然后每經(jīng)過(guò)period(ms)再次調(diào)度。
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
schedule方法的區(qū)別在于:
schedule在計(jì)算下一次執(zhí)行的時(shí)間的時(shí)候,是通過(guò)當(dāng)前時(shí)間(在任務(wù)執(zhí)行前得到) + 時(shí)間片,而scheduleAtFixedRate方法是通過(guò)當(dāng)前需要執(zhí)行的時(shí)間(也就是計(jì)算出現(xiàn)在應(yīng)該執(zhí)行的時(shí)間)+ 時(shí)間片,前者是運(yùn)行的實(shí)際時(shí)間,而后者是理論時(shí)間點(diǎn)。比如:
- schedule 時(shí)間片是 5s,那么理論上會(huì)在 5、10、15、20這些時(shí)間片被調(diào)度,但是如果由于某些 CPU 征用導(dǎo)致未被調(diào)度,假如等到第 8s 才被第一次調(diào)度,那么 schedule 方法計(jì)算出來(lái)的下一次時(shí)間應(yīng)該是第 13s 而不是第 10s
- scheduleAtFixedRate 方法就是每次理論計(jì)算出下一次需要調(diào)度的時(shí)間用以排序,若第8s被調(diào)度,那么計(jì)算出應(yīng)該是第 10s,所以它距離當(dāng)前時(shí)間是 2s
在到了指定時(shí)間后開(kāi)始調(diào)度,每次調(diào)度完后,最少等待period(ms)后才開(kāi)始調(diào)度。
public void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)
內(nèi)部結(jié)構(gòu)
Timer 類(lèi)里包含一個(gè)任務(wù)隊(duì)列和一個(gè)異步輪詢(xún)線(xiàn)程。任務(wù)隊(duì)列里容納了所有待執(zhí)行的任務(wù),所有的任務(wù)將會(huì)在這一個(gè)異步線(xiàn)程里執(zhí)行,切記:
- 任務(wù)的執(zhí)行代碼不可以?huà)伋霎惓?,否則會(huì)導(dǎo)致 Timer 線(xiàn)程掛掉,所有的任務(wù)都沒(méi)得執(zhí)行了。
- **單個(gè)任務(wù)也不易執(zhí)行時(shí)間太長(zhǎng),否則會(huì)影響任務(wù)調(diào)度在時(shí)間上的精準(zhǔn)性。**比如你一個(gè)任務(wù)跑了太久,其它等著調(diào)度的任務(wù)就一直處于饑餓狀態(tài)得不到調(diào)度。所有任務(wù)的執(zhí)行都是這單一的 TimerThread 線(xiàn)程。
public class Timer { private final TaskQueue queue = new TaskQueue(); private final TimerThread thread = new TimerThread(queue); }
Timer 的任務(wù)隊(duì)列 TaskQueue 是一個(gè)特殊的隊(duì)列,它內(nèi)部是一個(gè)數(shù)組。這個(gè)數(shù)組會(huì)按照待執(zhí)行時(shí)間進(jìn)行堆排序,堆頂元素總是待執(zhí)行時(shí)間最小的任務(wù)。
更多關(guān)于Jave時(shí)間類(lèi)庫(kù)Timer的使用方法與實(shí)例請(qǐng)查看下面的相關(guān)鏈接
相關(guān)文章
Java中使用jaxp進(jìn)行sax解析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
使用SAX的優(yōu)勢(shì)在于其解析速度較快,相對(duì)于DOM而言占用內(nèi)存較少。這篇文章主要介紹了Java中使用jaxp進(jìn)行sax解析,需要的朋友可以參考下2017-08-08基于Java實(shí)現(xiàn)一個(gè)復(fù)雜關(guān)系表達(dá)式過(guò)濾器
這篇文章主要為大家詳細(xì)介紹了如何基于Java實(shí)現(xiàn)一個(gè)復(fù)雜關(guān)系表達(dá)式過(guò)濾器。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-07-07詳解SpringBoot配置文件啟動(dòng)時(shí)動(dòng)態(tài)配置參數(shù)方法
這篇文章主要介紹了詳解SpringBoot配置文件啟動(dòng)時(shí)動(dòng)態(tài)配置參數(shù)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情
這篇文章主要介紹了Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09Springboot集成MongoDB無(wú)認(rèn)證與開(kāi)啟認(rèn)證的配置方式
本文主要介紹了Springboot集成MongoDB無(wú)認(rèn)證與開(kāi)啟認(rèn)證的配置方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03Mybatis如何實(shí)現(xiàn)關(guān)聯(lián)屬性懶加載
這篇文章主要介紹了Mybatis如何實(shí)現(xiàn)關(guān)聯(lián)屬性懶加載的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07