最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java定時任務(wù)Timer、TimerTask與ScheduledThreadPoolExecutor詳解

 更新時間:2024年01月23日 09:26:34   作者:碼靈  
這篇文章主要介紹了Java定時任務(wù)Timer、TimerTask與ScheduledThreadPoolExecutor詳解,  定時任務(wù)就是在指定時間執(zhí)行程序,或周期性執(zhí)行計劃任務(wù),Java中實現(xiàn)定時任務(wù)的方法有很多,本文從從JDK自帶的一些方法來實現(xiàn)定時任務(wù)的需求,需要的朋友可以參考下

一、Timer和TimerTask

Timer和TimerTask可以作為線程實現(xiàn)的常見方式,JDK1.5之后定時任務(wù)推薦使用ScheduledThreadPoolExecutor。

1、快速入門

Timer運行在后臺,可以執(zhí)行任務(wù)一次,或定期執(zhí)行任務(wù)。TimerTask類繼承了Runnable接口,因此具備多線程的能力。

一個Timer可以調(diào)度任意多個TimerTask,所有任務(wù)都存儲在一個隊列中順序執(zhí)行,如果需要多個TimerTask并發(fā)執(zhí)行,則需要創(chuàng)建兩個多個Timer。

一個簡單使用Timer的例子如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest { 
    //被執(zhí)行的任務(wù)必須繼承TimerTask,并且實現(xiàn)run方法
    static class MyTimerTask1 extends TimerTask { 
        public void run() { 
            System.out.println("爆炸?。?!"); 
        } 
    }    
    public static void main(String[] args) throws ParseException { 
        Timer timer = new Timer(); 
        //1、設(shè)定兩秒后執(zhí)行任務(wù)
        //timer.scheduleAtFixedRate(new MyTimerTask1(), 2000,1000);
        //2、設(shè)定任務(wù)在執(zhí)行時間執(zhí)行,本例設(shè)定時間13:57:00
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
        Date time = dateFormatter.parse("2023/02/11 14:40:00"); 
        timer.schedule(new MyTimerTask1(), time);
    } 
} 

2、schedule與scheduleAtFixedRate使用方法

  • schedule(TimerTask task, long delay, long period) --指定任務(wù)執(zhí)行延遲時間
  • schedule(TimerTask task, Date time, long period) --指定任務(wù)執(zhí)行時刻
  • scheduleAtFixedRate(TimerTask task, long delay, long period)
  • scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

3、schedule與scheduleAtFixedRate區(qū)別

1) schedule:

①注重任務(wù)執(zhí)行的平滑度,也就是說任務(wù)隊列中某個任務(wù)執(zhí)行延遲了某個時間,接下來的其余任務(wù)都會延遲相同時間,來最大限度的保證任務(wù)與任務(wù)之間的時間間隔的完整性;

②當(dāng)程序指定開始時刻(Date time)小于當(dāng)前系統(tǒng)時刻時,會立即執(zhí)行一次任務(wù),之后的任務(wù)開始執(zhí)行時間以當(dāng)前時刻為標(biāo)準(zhǔn),結(jié)合時間間隔計算得到;

例:計劃任務(wù)程序指定從2023/02/11 18:00:00開始每隔3分鐘執(zhí)行一次任務(wù)。如果該程序在18:00:00之前運行,則計劃任務(wù)程序分別會在18:00:00、18:03:00、18:06:00...等時間點執(zhí)行任務(wù);如果該程序在18:00:00之后運行,如在18:07:00時刻開始運行程序,計劃任務(wù)程序判斷指定開始執(zhí)行時刻18:00:00小于當(dāng)前系統(tǒng)時刻,于是立即執(zhí)行一次任務(wù),接下來任務(wù)時間時刻分別為18:10:00、18:13:00、18:16:00...;而當(dāng)使用scheduleAtFixedRate執(zhí)行計劃任務(wù)時,無論計劃任務(wù)程序在什么時候運行,所有任務(wù)執(zhí)行的次數(shù)都按照原計劃,不會因為程序執(zhí)行時刻的早晚而改變。而當(dāng)程序運行時刻比計劃任務(wù)計劃首次執(zhí)行時間晚時,如同樣在18:07:00時刻開始執(zhí)行程序,則計劃任務(wù)程序會立馬計算程序執(zhí)行時刻晚于指定時刻,會立即執(zhí)行(18:07:00-18:00:00)/3+1=3次任務(wù)(代表18:00:00、18:03:00和18:06:00三個時刻執(zhí)行的任務(wù)),接下來任務(wù)執(zhí)行時刻是18:09:00、18:12:00等。

 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerRateFix {
    public static void main(String[] args) throws ParseException {
        final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
        Date startDate = dateFormatter.parse("2023/02/11 18:00:00"); 
        Timer timer = new Timer(); 
        timer.schedule(new TimerTask(){ 
           public void run() 
           { 
               System.out.println("執(zhí)行任務(wù),當(dāng)前時刻:" + dateFormatter.format(new Date())); 
           } 
        },startDate,3*60*1000); 
    }
}

③ 當(dāng)執(zhí)行任務(wù)的時間間隔t1大于周期間隔t2時,下一次任務(wù)執(zhí)行時間點相對于上一次任務(wù)實際執(zhí)行完成的時間點,每個任務(wù)的執(zhí)行時間會延后,第n個計劃任務(wù)的實際執(zhí)行時間比預(yù)計要延后(t1-t2)*n個時間單位。

例:計劃任務(wù)程序指定從2023/02/11 18:00:00開始每隔5秒執(zhí)行一次任務(wù),每次任務(wù)執(zhí)行時間為6秒。當(dāng)程序在18:00:00之前執(zhí)行時,schedule分別會在18:00:00、18:00:06、18:00:12...等時間點執(zhí)行計劃任務(wù),每隔時間點間隔6秒。原因是根據(jù)計劃,第一個計劃任務(wù)應(yīng)會在18:00:00執(zhí)行,第二個計劃任務(wù)應(yīng)會在18:00:05執(zhí)行,而在18:00:05時間點,第一個任務(wù)才執(zhí)行了5秒,還需要1秒才執(zhí)行結(jié)束,因此第二個任務(wù)不能執(zhí)行,于是等待1秒后在18:00:06時刻執(zhí)行,之后每個任務(wù)均如此,均比原定執(zhí)行時刻有延遲,每個任務(wù)時間間隔為6秒。當(dāng)使用scheduleAtFixedRate執(zhí)行計劃任務(wù)時,第一個計劃任務(wù)在18:00:00時刻執(zhí)行,第二個會根據(jù)計劃在18:00:05執(zhí)行,第三個會在18:00:10執(zhí)行,每個任務(wù)執(zhí)行時間間隔為5秒,詳細(xì)執(zhí)行情況如下圖所示

圖1 schedule與scheduleAtFixedRate任務(wù)執(zhí)行區(qū)別

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Timer; 
import java.util.TimerTask; 
public class TimerRateTest { 
    public static void main(String[] args) throws ParseException { 
        final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
        Timer timer = new Timer(); 
        Date time = dateFormatter.parse("2023/02/11 18:00:00");
        //假設(shè)程序在2023/02/11 18:00:00之前啟動
        //1、使用scheduleAtFixedRate,每個計劃任務(wù)執(zhí)行時間點嚴(yán)格為18:00:00、18:00:05、18:00:10...,當(dāng)任務(wù)執(zhí)行時間大于時間間隔時可能會有并發(fā)情況
        //2、使用schedule,每個計劃任務(wù)執(zhí)行時間點根據(jù)上一個任務(wù)執(zhí)行結(jié)束時間及時間間隔來計算
        //     當(dāng)任務(wù)執(zhí)行時間t1>時間間隔t2時,第N個計劃任務(wù)執(zhí)行時間點延遲為(t1-t2)*N,執(zhí)行時間點為18:00:00+t2*(N-1)+(t1-t2)*N
        //    當(dāng)任務(wù)執(zhí)行時間t1<=時間間隔t2時,第N個計劃任務(wù)執(zhí)行時間點無延遲,執(zhí)行時間為原計劃
        timer.scheduleAtFixedRate(new TimerTask(){ 
           public void run() { 
               try { 
                   //每個計劃任務(wù)執(zhí)行時間為6秒
                   Thread.sleep(6000); 
               } catch (InterruptedException e) { 
                   e.printStackTrace(); 
               }
               System.out.println("結(jié)束當(dāng)前任務(wù),當(dāng)前時間:"+ dateFormatter.format(new Date())); 
           } 
        },time,5000);  //計劃任務(wù)執(zhí)行時間間隔為5秒
    } 
} 

2)scheduleAtFixedRate:

①注重任務(wù)執(zhí)行的頻度,也就是說計劃任務(wù)程序開始執(zhí)行,每隔任務(wù)執(zhí)行的時間點就已經(jīng)確定,并不會因為某個任務(wù)的延遲而延遲執(zhí)行其他任務(wù),可以保證任務(wù)執(zhí)行的時間效率;

②當(dāng)程序指定開始時刻(Date firstTime)小于當(dāng)前系統(tǒng)時刻時,會立即執(zhí)行任務(wù),執(zhí)行次數(shù)為(當(dāng)前系統(tǒng)時刻-指定開始時刻)/時間間隔,之后的任務(wù)開始執(zhí)行時刻與當(dāng)前系統(tǒng)時刻無關(guān),仍按照程序指定開始時刻根據(jù)時間間隔計算得到;

③當(dāng)執(zhí)行任務(wù)的時間間隔t1大于周期間隔t2時,下一次任務(wù)執(zhí)行時間點還是按照原定計劃不變,加入阻塞隊列,等待上一個任務(wù)完成,立即執(zhí)行;只要滿足周期就會加入阻塞隊列。

4、終止Timer線程

1) 調(diào)用Timer.cancle()方法??梢栽诔绦蛉魏蔚胤秸{(diào)用,甚至在TimerTask中的run方法中調(diào)用;

2) 創(chuàng)建Timer時定義位daemon守護(hù)線程,使用new Timer(true)語句;

3) 設(shè)置Timer對象為null,其會自動終止;

4) 調(diào)用System.exit方法,整個程序終止。

5、Timer線程的缺點

1) Timer線程不會捕獲異常,所以TimerTask拋出的未檢查的異常會終止timer線程。如果Timer線程中存在多個計劃任務(wù),其中一個計劃任務(wù)拋出未檢查的異常,則會引起整個Timer線程結(jié)束,從而導(dǎo)致其他計劃任務(wù)無法得到繼續(xù)執(zhí)行?! ?/p>

2) Timer線程時基于絕對時間(如:2023/02/14 16:06:00),因此計劃任務(wù)對系統(tǒng)的時間的改變是敏感的。

3) Timer是單線程,如果某個任務(wù)很耗時,可能會影響其他計劃任務(wù)的執(zhí)行。

因此,JDK1.5以上建議使用ScheduledThreadPoolExecutor來代替Timer執(zhí)行計劃任務(wù)?!  ?/p>

二、ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor是JDK1.5以后推出的類,用于實現(xiàn)定時、重復(fù)執(zhí)行的功能,官方文檔解釋要優(yōu)于Timer。

1、構(gòu)造方法  

1)ScheduledThreadPoolExecutor(int corePoolSize) 使用給定核心池大小創(chuàng)建一個新定定時線程池

2)ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactorythreadFactory) 使用給定的初始參數(shù)創(chuàng)建一個新對象,可提供線程創(chuàng)建工廠

private final static ScheduledThreadPoolExecutor schedual = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
        private AtomicInteger atoInteger = new AtomicInteger(0);
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName("xxx-Thread "+ atoInteger.getAndIncrement());
            return t;
        }
});

2、調(diào)度方法

1)schedule(Callable callable, long delay, TimeUnit unit); 延遲delay時間后開始執(zhí)行callable

2)scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); 延遲initialDelay時間后開始執(zhí)行command,并且按照period時間周期性重復(fù)調(diào)用,當(dāng)任務(wù)執(zhí)行時間大于間隔時間時,之后的任務(wù)都會延遲,此時與Timer中的scheduleAtFixedRate方法類似。

3)scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); 延遲initialDelay時間后開始執(zhí)行command,并且按照period時間周期性重復(fù)調(diào)用,這里的間隔時間delay是等上一個任務(wù)完全執(zhí)行完畢才開始計算。

圖2 ScheduledThreadPoolExecutor.scheduleWithFixedDelay與Timer.scheduleAtFixedRate任務(wù)執(zhí)行區(qū)別

3、與Timer相比,優(yōu)點

1) ScheduledThreadPoolExecutor線程會捕獲任務(wù)重的異常,即使多個計劃任務(wù)中存在某幾個計劃任務(wù)為捕獲異常的情況,也不會影響ScheduledThreadPoolExecutor總線程的工作,不會影響其他計劃任務(wù)的繼續(xù)執(zhí)行。

2)ScheduledThreadPoolExecutor是基于相對時間的,對系統(tǒng)時間的改變不敏感,但是如果執(zhí)行某一絕對時間(如2023/02/14 17:13:06)執(zhí)行任務(wù)(整秒 、整分執(zhí)行任務(wù)),可能不好執(zhí)行,此時可使用Timer。

3) ScheduledThreadPoolExecutor是線程池,如任務(wù)數(shù)過多或某些任務(wù)執(zhí)行時間較長,可自動分配更多的線程來執(zhí)行計劃任務(wù)。

總之,JDK1.5之后,計劃任務(wù)建議使用ScheduledThreadPoolExecutor。

到此這篇關(guān)于Java定時任務(wù)Timer、TimerTask與ScheduledThreadPoolExecutor詳解的文章就介紹到這了,更多相關(guān)Java定時任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java通過JavaMail發(fā)送郵件功能

    Java通過JavaMail發(fā)送郵件功能

    這篇文章主要為大家詳細(xì)介紹了Java通過JavaMail發(fā)送郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • java中BigDecimal的操作方法

    java中BigDecimal的操作方法

    這篇文章主要介紹了java中BigDecimal的操作方法,較為詳細(xì)的分析了BigDecimal類在進(jìn)行商業(yè)計算時的應(yīng)用方法,精度以及注意事項等問題,需要的朋友可以參考下
    2014-12-12
  • Java動態(tài)追蹤技術(shù)探究之從JSP到Arthas

    Java動態(tài)追蹤技術(shù)探究之從JSP到Arthas

    這篇文章主要介紹了Java動態(tài)追蹤技術(shù)探究之從JSP到Arthas,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下
    2019-06-06
  • Java運算符的知識點與代碼匯總

    Java運算符的知識點與代碼匯總

    這篇文章主要給大家總結(jié)介紹了關(guān)于Java運算符知識點與代碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • SpringBoot3文件管理操作方法

    SpringBoot3文件管理操作方法

    這篇文章主要介紹了SpringBoot3文件管理,本文案例只圍繞普通文件和Excel兩種類型進(jìn)行代碼實現(xiàn),包括工程搭建、上傳下載操作,需要的朋友可以參考下
    2023-08-08
  • Java程序的邏輯控制和方法詳解

    Java程序的邏輯控制和方法詳解

    這篇文章主要介紹了Java程序的邏輯控制和方法詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java中的volatile關(guān)鍵字經(jīng)典應(yīng)用場景和常見問題

    Java中的volatile關(guān)鍵字經(jīng)典應(yīng)用場景和常見問題

    這篇文章主要介紹了Java中volatile關(guān)鍵字經(jīng)典應(yīng)用場景和常見問題的相關(guān)資料,volatile是一種輕量級鎖的實現(xiàn),它針對的僅僅是共享變量,不會對線程加鎖,更不會造成線程的阻塞,需要的朋友可以參考下
    2026-03-03
  • java中Ajax與Axios的使用小結(jié)

    java中Ajax與Axios的使用小結(jié)

    在項目中我們經(jīng)常會遇到需要向請求頭中添加消息的場景,本文主要介紹了java中Ajax與Axios的使用小結(jié),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • Android 屏幕分辨率的整理

    Android 屏幕分辨率的整理

    這篇文章主要介紹了Android 屏幕分辨率的整理的相關(guān)資料,這里整理了常見的分辨率希望能幫助到大家,需要的朋友可以參考下
    2017-08-08
  • 解決Feign配置RequestContextHolder.getRequestAttributes()為null的問題

    解決Feign配置RequestContextHolder.getRequestAttributes()為null的問題

    這篇文章主要介紹了解決Feign配置RequestContextHolder.getRequestAttributes()為null的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論

赤峰市| 乐昌市| 三河市| 渝中区| 翁牛特旗| 太仓市| 彰化市| 德阳市| 东乡县| 巴东县| 清丰县| 宣城市| 吴堡县| 法库县| 尼勒克县| 油尖旺区| 府谷县| 龙岩市| 杂多县| 陵川县| 长沙市| 绍兴县| 宝清县| 利川市| 荔浦县| 于田县| 察隅县| 平顺县| 庆城县| 阳谷县| 福建省| 德兴市| 奈曼旗| 漠河县| 辽阳县| 庄浪县| 建德市| 汪清县| 弥渡县| 两当县| 翁源县|