亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

springboot實(shí)現(xiàn)定時(shí)任務(wù)的四種方式小結(jié)

 更新時(shí)間:2023年01月13日 15:15:24   作者:六六的小帥  
本文主要介紹了springboot實(shí)現(xiàn)定時(shí)任務(wù)的四種方式小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

因?yàn)槟承┬枨螅谔囟ǖ臅r(shí)間執(zhí)行一些任務(wù),比如定時(shí)刪除服務(wù)器存儲(chǔ)的數(shù)據(jù)緩存,定時(shí)獲取數(shù)據(jù)以及定時(shí)發(fā)送推送等等,這時(shí)就需要用到定時(shí)任務(wù)了。定時(shí)任務(wù),指的是在編程過(guò)程中無(wú)須做復(fù)雜控制的前提下執(zhí)行簡(jiǎn)單的定時(shí)操作。

Timer

在java中一個(gè)完整的定時(shí)任務(wù)可以用Timer和TimerTask兩個(gè)類配合完成。

Timer是一種工具,線程用其安排在后臺(tái)線程中執(zhí)行的任務(wù),可安排任務(wù)執(zhí)行一次或者定期重復(fù)執(zhí)行。

TimerTask是由Timer安排執(zhí)行一次或者重復(fù)執(zhí)行的任務(wù)。

Timer中提供了四個(gè)方法:

(1)schedule(TimerTask task,Date time)——安排在指定的時(shí)間執(zhí)行指定的任務(wù)

(2)schedule(TimerTask task,Date firstTime,long period)——安排指定的任務(wù)在指定的時(shí)間開始進(jìn)行重復(fù)的固定延遲執(zhí)行

(3)schedule(TimerTask task,long delay)——安排在指定延遲后執(zhí)行指定的任務(wù)

(4)schedule(TimerTask task,long delay,long period)——安排指定的任務(wù)在指定的延遲后開始進(jìn)行重復(fù)的固定速率執(zhí)行

示例:

首先需要?jiǎng)?chuàng)建一個(gè)類作為定時(shí)任務(wù),該類需要繼承TimerTask

public class TimerTask extends java.util.TimerTask{?
?? ?@Override
?? ?public void run() {
?? ??? ?//這里執(zhí)行定時(shí)任務(wù)內(nèi)容
?? ??? ?System.out.println("+++++++");
?? ?}?? ?
}

然后創(chuàng)建Timer調(diào)用之前創(chuàng)建的定時(shí)任務(wù)

public class TimerTest {
?? ?
?? ?public static void main(String[] args) {
?? ??? ?Timer timer = new Timer();
?? ??? ?TimerTask noticeTask = new TimerTask();
?? ??? ?timer.schedule(noticeTask,0,2000);
?? ??? ?timer.cancel();
?? ??? ?System.out.println("結(jié)束");?? ?
?? ?}
?
}

這樣定時(shí)執(zhí)行任務(wù)的功能就實(shí)現(xiàn)了,但Timer有著一定的缺陷:

Timer對(duì)于系統(tǒng)時(shí)間的改變非常敏感,它對(duì)調(diào)度的支持是基于絕對(duì)時(shí)間而不是相對(duì)時(shí)間。

Timer線程是不會(huì)捕獲異常的,多線程并行處理定時(shí)任務(wù)時(shí),Timer運(yùn)行多個(gè)TimerTask時(shí),只要其中之一沒有捕獲拋出的異常,其他任務(wù)便會(huì)自動(dòng)終止運(yùn)行。同時(shí)Timer也不會(huì)重新恢復(fù)線程的執(zhí)行,它會(huì)錯(cuò)誤的認(rèn)為整個(gè)Timer線程都會(huì)取消,已經(jīng)被安排但尚未執(zhí)行的TimerTask也不會(huì)再執(zhí)行了,新的任務(wù)也不能被調(diào)度。因此,如果TimerTask拋出未檢查的異常,Timer將會(huì)產(chǎn)生無(wú)法預(yù)料的行為。

ScheduledExecutor

Timer是基于絕對(duì)時(shí)間的,對(duì)系統(tǒng)時(shí)間比較敏感,而ScheduledExecutor則是基于相對(duì)時(shí)間。

Timer的內(nèi)部只有一個(gè)線程,如果有多個(gè)任務(wù)的話就會(huì)順序執(zhí)行,這樣我們的延遲時(shí)間和循環(huán)時(shí)間就會(huì)出現(xiàn)問(wèn)題。而ScheduledThreadPoolExecutor內(nèi)部是個(gè)線程池,可以支持多個(gè)任務(wù)并發(fā)執(zhí)行,在對(duì)延遲任務(wù)和循環(huán)任務(wù)要求嚴(yán)格的時(shí)候,就需要考慮使用ScheduledExecutor了。

針對(duì)Timer類存在的缺陷,Java 5 推出了基于線程池設(shè)計(jì)的 ScheduledExecutor,ScheduledExecutor的設(shè)計(jì)思想是每一個(gè)被調(diào)度的任務(wù)都會(huì)由線程池中一個(gè)線程去執(zhí)行,因此任務(wù)是并發(fā)的,相互之間不會(huì)受到干擾,只有當(dāng)任務(wù)的時(shí)間到來(lái)時(shí),ScheduledExecutor才會(huì)真正啟動(dòng)一個(gè)線程,其余時(shí)間ScheduledExecutor都是處于輪詢?nèi)蝿?wù)的狀態(tài)。如果我們?cè)O(shè)定的調(diào)度周期小于任務(wù)運(yùn)行時(shí)間,該任務(wù)會(huì)被重復(fù)添加到一個(gè)延時(shí)任務(wù)隊(duì)列,所以同一時(shí)間任務(wù)隊(duì)列中會(huì)有多個(gè)任務(wù)待調(diào)度,線程池會(huì)首先獲取優(yōu)先級(jí)高的任務(wù)執(zhí)行。效果就是任務(wù)運(yùn)行多長(zhǎng)時(shí)間,調(diào)度時(shí)間就會(huì)變?yōu)槎嗑?,因?yàn)樘砑拥饺蝿?wù)隊(duì)列的任務(wù)的延時(shí)時(shí)間每次都是負(fù)數(shù),所以會(huì)被立刻執(zhí)行。

示例:

public class MyScheduledExecutor implements Runnable{
?? ?
? ? private String jobName;
? ??
? ? MyScheduledExecutor() {
? ? ? ??
? ? }
? ??
? ? MyScheduledExecutor(String jobName) {
? ? ? ? this.jobName = jobName;
? ? }
?
? ? @Override
? ? public void run() {
?? ? ? ?System.out.println(jobName + " is running");
? ? }
?
}
public class MyScheduledExecutorService {
 
    public static void main(String[] args) {
        
        long initialDelay = 3;
        long period = 1;
 
            /**
            *     創(chuàng)建一個(gè)線程池,它可安排在給定延遲后運(yùn)行任務(wù)或者定期地執(zhí)行任務(wù)
            *    參數(shù):corePoolSize - 池中所保存的線程數(shù),即使線程是空閑的也包括在內(nèi)
            */
            ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
        
        /**
         *     從現(xiàn)在開始3秒鐘之后,每隔1秒鐘執(zhí)行一次job1,ScheduleAtFixedRate是基于固定時(shí)間間隔進(jìn)行任務(wù)調(diào)度
         *    參數(shù):1、任務(wù)體 2、首次執(zhí)行的延時(shí)時(shí)間
             *        3、任務(wù)執(zhí)行間隔 4、間隔時(shí)間單位
         */
        service.scheduleAtFixedRate(new MyScheduledExecutor("job1"), initialDelay, period, TimeUnit.SECONDS);
        
        /**
         * 從現(xiàn)在開始3秒鐘之后,每隔1秒鐘執(zhí)行一次job2,ScheduleWithFixedDelay 取決于每次任務(wù)執(zhí)行的時(shí)間長(zhǎng)短,基于不固定時(shí)間間隔進(jìn)行任務(wù)調(diào)度
         */
        service.scheduleWithFixedDelay(new MyScheduledExecutor("job2"), initialDelay, period, TimeUnit.SECONDS);
    }
    
}

ScheduledExecutor 配合 Calendar 實(shí)現(xiàn)復(fù)雜任務(wù)調(diào)度

示例:設(shè)置每星期二的 18:30:00 執(zhí)行任務(wù)

使用 ScheduledExcetuor 和 Calendar 進(jìn)行任務(wù)調(diào)度

public class ScheduledExceutorTest2 extends TimerTask {
?
?? ?private String jobName = "";
?
?? ?public ScheduledExceutorTest2(String jobName) {
?? ??? ?super();
?? ??? ?this.jobName = jobName;
?? ?}
?
?? ?@Override
?? ?public void run() {
?? ??? ?System.out.println("Date = " + new Date() + ", execute " + jobName);
?? ?}
?
?? ?/**
?? ? * 計(jì)算從當(dāng)前時(shí)間currentDate開始,滿足條件dayOfWeek, hourOfDay, minuteOfHour,
?? ? * secondOfMinite的最近時(shí)間
?? ? */
?? ?public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek, int hourOfDay, int minuteOfHour,
?? ??? ??? ?int secondOfMinite) {
?? ??? ?// 計(jì)算當(dāng)前時(shí)間的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各個(gè)字段值
?? ??? ?int currentWeekOfYear = currentDate.get(Calendar.WEEK_OF_YEAR);
?? ??? ?int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK);
?? ??? ?int currentHour = currentDate.get(Calendar.HOUR_OF_DAY);
?? ??? ?int currentMinute = currentDate.get(Calendar.MINUTE);
?? ??? ?int currentSecond = currentDate.get(Calendar.SECOND);
?? ??? ?// 如果輸入條件中的dayOfWeek小于當(dāng)前日期的dayOfWeek,則WEEK_OF_YEAR需要推遲一周
?? ??? ?boolean weekLater = false;
?? ??? ?if (dayOfWeek < currentDayOfWeek) {
?? ??? ??? ?weekLater = true;
?? ??? ?} else if (dayOfWeek == currentDayOfWeek) {
?? ??? ??? ?// 當(dāng)輸入條件與當(dāng)前日期的dayOfWeek相等時(shí),如果輸入條件中的
?? ??? ??? ?// hourOfDay小于當(dāng)前日期的
?? ??? ??? ?// currentHour,則WEEK_OF_YEAR需要推遲一周
?? ??? ??? ?if (hourOfDay < currentHour) {
?? ??? ??? ??? ?weekLater = true;
?? ??? ??? ?} else if (hourOfDay == currentHour) {
?? ??? ??? ??? ?// 當(dāng)輸入條件與當(dāng)前日期的dayOfWeek, hourOfDay相等時(shí),
?? ??? ??? ??? ?// 如果輸入條件中的minuteOfHour小于當(dāng)前日期的
?? ??? ??? ??? ?// currentMinute,則WEEK_OF_YEAR需要推遲一周
?? ??? ??? ??? ?if (minuteOfHour < currentMinute) {
?? ??? ??? ??? ??? ?weekLater = true;
?? ??? ??? ??? ?} else if (minuteOfHour == currentSecond) {
?? ??? ??? ??? ??? ?// 當(dāng)輸入條件與當(dāng)前日期的dayOfWeek, hourOfDay,
?? ??? ??? ??? ??? ?// minuteOfHour相等時(shí),如果輸入條件中的
?? ??? ??? ??? ??? ?// secondOfMinite小于當(dāng)前日期的currentSecond,
?? ??? ??? ??? ??? ?// 則WEEK_OF_YEAR需要推遲一周
?? ??? ??? ??? ??? ?if (secondOfMinite < currentSecond) {
?? ??? ??? ??? ??? ??? ?weekLater = true;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ??? ?if (weekLater) {
?? ??? ??? ?// 設(shè)置當(dāng)前日期中的WEEK_OF_YEAR為當(dāng)前周推遲一周
?? ??? ??? ?currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1);
?? ??? ?}
?? ??? ?// 設(shè)置當(dāng)前日期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND為輸入條件中的值。
?? ??? ?currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek);
?? ??? ?currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
?? ??? ?currentDate.set(Calendar.MINUTE, minuteOfHour);
?? ??? ?currentDate.set(Calendar.SECOND, secondOfMinite);
?? ??? ?return currentDate;
?? ?}
?
?? ?public static void main(String[] args) throws Exception {
?? ??? ?ScheduledExceutorTest2 test = new ScheduledExceutorTest2("job1");
?? ??? ?// 獲取當(dāng)前時(shí)間
?? ??? ?Calendar currentDate = Calendar.getInstance();
?? ??? ?long currentDateLong = currentDate.getTime().getTime();
?? ??? ?System.out.println("Current Date = " + currentDate.getTime().toString());
?? ??? ?// 計(jì)算滿足條件的最近一次執(zhí)行時(shí)間
?? ??? ?Calendar earliestDate = test.getEarliestDate(currentDate, 3, 18, 30, 00);
?? ??? ?long earliestDateLong = earliestDate.getTime().getTime();
?? ??? ?System.out.println("Earliest Date = " + earliestDate.getTime().toString());
?? ??? ?// 計(jì)算從當(dāng)前時(shí)間到最近一次執(zhí)行時(shí)間的時(shí)間間隔
?? ??? ?long delay = earliestDateLong - currentDateLong;
?? ??? ?// 計(jì)算執(zhí)行周期為一星期
?? ??? ?long period = 7 * 24 * 60 * 60 * 1000;
?? ??? ?ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
?? ??? ?// 從現(xiàn)在開始delay毫秒之后,每隔一星期執(zhí)行一次job1
?? ??? ?service.scheduleAtFixedRate(test, delay, period, TimeUnit.MILLISECONDS);
?? ?}
?
}

其核心在于根據(jù)當(dāng)前時(shí)間推算出最近一個(gè)星期二 18:30:00 的絕對(duì)時(shí)間,然后計(jì)算與當(dāng)前時(shí)間的時(shí)間差,作為調(diào)用 ScheduledExceutor 函數(shù)的參數(shù),計(jì)算最近時(shí)間要用到 java.util.calendar 的功能。

注解@Scheduled

Spring提供的注解,優(yōu)點(diǎn)就是配置簡(jiǎn)單,依賴少,缺點(diǎn)是同一個(gè)task,如果前一個(gè)還沒跑完后面一個(gè)就不會(huì)觸發(fā),不同的task也不能同時(shí)運(yùn)行。因?yàn)閟cheduler的默認(rèn)線程數(shù)為1,配置pool-size為2的話,會(huì)導(dǎo)致同一個(gè)task前一個(gè)還沒跑完后面又被觸發(fā)的問(wèn)題,不支持集群等。

示例:

yml文件配置:

time:

? ? cron: 0/5 * * * * *

? ? interval: 5

啟動(dòng)類添加@EnableScheduling

定時(shí)任務(wù):

@Component
public class TimeTask {
?? ?
?? ?@Scheduled(cron = "${time.cron}")
?? ?public void ?flush1() throws ?Exception{
? ? ? ? ? ? System.out.println("Execute1");
? ? ? ? }
?? ?
?? ?@Scheduled(cron = "0/${time.interval} * * * * ?")
?? ?public void ?flush2() throws ?Exception{
? ? ? ? ? ? System.out.println("Execute2");
? ? ? ? }
?? ?
?? ?@Scheduled(cron = "0/5 * * * * ?")
?? ?public void ?flush3() throws ?Exception{
? ? ? ? ? ? System.out.println("Execute3");
? ? ? ? }
?
}

參數(shù)介紹:

fixedDelay

上一次執(zhí)行完畢時(shí)間點(diǎn)之后多長(zhǎng)時(shí)間再執(zhí)行。如:

@Scheduled(fixedDelay = 5000) //上一次執(zhí)行完畢時(shí)間點(diǎn)之后5秒再執(zhí)行

fixedDelayString

與 fixedDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。如:

@Scheduled(fixedDelayString = "5000") //上一次執(zhí)行完畢時(shí)間點(diǎn)之后5秒再執(zhí)行

占位符的使用:

@Scheduled(fixedDelayString = "${time.fixedDelay}")
void testFixedDelayString() {
     System.out.println("Execute”);
}

fixedRate

上一次開始執(zhí)行時(shí)間點(diǎn)之后多長(zhǎng)時(shí)間再執(zhí)行。如:

@Scheduled(fixedRate = 5000) //上一次開始執(zhí)行時(shí)間點(diǎn)之后5秒再執(zhí)行

fixedRateString

與 fixedRate 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。

initialDelay

第一次延遲多長(zhǎng)時(shí)間后再執(zhí)行。如:

@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延遲1秒后執(zhí)行,之后按fixedRate的規(guī)則每5秒執(zhí)行一次

initialDelayString

與 initialDelayString 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。

cron表達(dá)式

cron表達(dá)式是一個(gè)字符串,字符串以5或6個(gè)空格隔開,分成6或7個(gè)域,每一個(gè)域代表一個(gè)含義。

cron表達(dá)式語(yǔ)法:

[秒]   [分]   [小時(shí)]   [日]   [月]   [周]   [年]

注:[年]不是必須的域,可以省略[年],則一共6個(gè)域

其中各個(gè)域的定義如下:

序號(hào)說(shuō)明必填允許填寫的值允許的通配符
10-59, - * /
20-59, - * /
3時(shí)0-23, - * /
41月31日, - * ? / L W
51-12 / JAN-DEC, - * /
61-7 / SUN-SAT, - * ? / L #
71970-2099, - * /

Cron表達(dá)式對(duì)特殊字符的大小寫不敏感,對(duì)代表星期的縮寫英文大小寫也不敏感。星號(hào)(*):可用在所有字段中,表示對(duì)應(yīng)時(shí)間域的每一個(gè)時(shí)刻,例如, 在分鐘字段時(shí),表示“每分鐘”;
問(wèn)號(hào)(?):該字符只在日期和星期字段中使用,它通常指定為“無(wú)意義的值”,相當(dāng)于點(diǎn)位符;

  • 減號(hào)(-):表達(dá)一個(gè)范圍,如在小時(shí)字段中使用“10-12”,則表示從10到12點(diǎn),即10,11,12;
  • 逗號(hào)(,):表達(dá)一個(gè)列表值,如在星期字段中使用“MON,WED,FRI”,則表示星期一,星期三和星期五;
  • 斜杠(/):x/y表達(dá)一個(gè)等步長(zhǎng)序列,x為起始值,y為增量步長(zhǎng)值。如在分鐘字段中使用0/15,則表示為0,15,30和45秒,而5/15在分鐘字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;
  • L:該字符只在日期和星期字段中使用,代表“Last”的意思,但它在兩個(gè)字段中意思不同。L在日期字段中,表示這個(gè)月份的最后一天,如一月的31號(hào),非閏年二月的28號(hào);如果L用在星期中,則表示星期六,等同于7。但是,如果L出現(xiàn)在星期字段里,而且在前面有一個(gè)數(shù)值X,則表示“這個(gè)月的最后X天”,例如,6L表示該月的最后星期五;
  • W:該字符只能出現(xiàn)在日期字段里,是對(duì)前導(dǎo)日期的修飾,表示離該日期最近的工作日。例如15W表示離該月15號(hào)最近的工作日,如果該月15號(hào)是星期六,則匹配14號(hào)星期五;如果15日是星期日,則匹配16號(hào)星期一;如果15號(hào)是星期二,那結(jié)果就是15號(hào)星期二。但必須注意關(guān)聯(lián)的匹配日期不能夠跨月,如你指定1W,如果1號(hào)是星期六,結(jié)果匹配的是3號(hào)星期一,而非上個(gè)月最后的那天。W字符串只能指定單一日期,而不能指定日期范圍;
  • LW組合:在日期字段可以組合使用LW,它的意思是當(dāng)月的最后一個(gè)工作日;
  • 井號(hào)(#):該字符只能在星期字段中使用,表示當(dāng)月某個(gè)工作日。如6#3表示當(dāng)月的第三個(gè)星期五(6表示星期五,#3表示當(dāng)前的第三個(gè)),而4#5表示當(dāng)月的第五個(gè)星期三,假設(shè)當(dāng)月沒有第五個(gè)星期三,忽略不觸發(fā);
  • C:該字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是計(jì)劃所關(guān)聯(lián)的日期,如果日期沒有被關(guān)聯(lián),則相當(dāng)于日歷中所有日期。例如5C在日期字段中就相當(dāng)于日歷5日以后的第一天。1C在星期字段中相當(dāng)于星期日后的第一天。

示例:

表示式說(shuō)明
0 0 12 * * ?每天12點(diǎn)運(yùn)行
0 15 10 ? * *每天10:15運(yùn)行
0 15 10 * * ?每天10:15運(yùn)行
0 15 10 * * ? *每天10:15運(yùn)行
0 15 10 * * ? 2008在2008年的每天10:15運(yùn)行
0 * 14 * * ?每天14點(diǎn)到15點(diǎn)之間每分鐘運(yùn)行一次,開始于14:00,結(jié)束于14:59。
0 0/5 14 * * ?每天14點(diǎn)到15點(diǎn)每5分鐘運(yùn)行一次,開始于14:00,結(jié)束于14:55。
0 0/5 14,18 * * ?每天14點(diǎn)到15點(diǎn)每5分鐘運(yùn)行一次,此外每天18點(diǎn)到19點(diǎn)每5鐘也運(yùn)行一次。
0 0-5 14 * * ?每天14:00點(diǎn)到14:05,每分鐘運(yùn)行一次。
0 10,44 14 ? 3 WED3月每周三的14:10分到14:44,每分鐘運(yùn)行一次。
0 15 10 ? * MON-FRI每周一,二,三,四,五的10:15分運(yùn)行。
0 15 10 15 * ?每月15日10:15分運(yùn)行。
0 15 10 L * ?每月最后一天10:15分運(yùn)行。
0 15 10 ? * 6L每月最后一個(gè)星期五10:15分運(yùn)行。
0 15 10 ? * 6L 2007-2009在2007,2008,2009年每個(gè)月的最后一個(gè)星期五的10:15分運(yùn)行。
0 15 10 ? * 6#3每月第三個(gè)星期五的10:15分運(yùn)行。

Quartz

Quartz 是一個(gè)完全由 Java 編寫的開源作業(yè)調(diào)度框架,它可以集成在幾乎任何Java應(yīng)用程序中進(jìn)行作業(yè)調(diào)度。

Quartz 可以與 J2EE 與 J2SE 應(yīng)用程序相結(jié)合也可以單獨(dú)使用。

Quartz 允許程序開發(fā)人員根據(jù)時(shí)間的間隔來(lái)調(diào)度作業(yè)。

Quartz 實(shí)現(xiàn)了作業(yè)和觸發(fā)器的多對(duì)多的關(guān)系,還能把多個(gè)作業(yè)與不同的觸發(fā)器關(guān)聯(lián)。

Quartz的運(yùn)行環(huán)境

Quartz 可以運(yùn)行嵌入在另一個(gè)獨(dú)立式應(yīng)用程序。

Quartz 可以在應(yīng)用程序服務(wù)器(或 servlet 容器)內(nèi)被實(shí)例化,并且參與 XA 事務(wù)。

Quartz 可以作為一個(gè)獨(dú)立的程序運(yùn)行(其自己的 Java 虛擬機(jī)內(nèi)),可以通過(guò) RMI 使用。

Quartz 可以被實(shí)例化,作為獨(dú)立的項(xiàng)目集群(負(fù)載平衡和故障轉(zhuǎn)移功能),用于作業(yè)的執(zhí)行。

Job

代表一個(gè)工作,要執(zhí)行的具體內(nèi)容。此接口中只有一個(gè)方法,如下:

public class QuartzJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println(new Date());
    }
}

可以通過(guò)實(shí)現(xiàn)該接口來(lái)定義需要執(zhí)行的任務(wù)。

JobDetail

用于定義作業(yè)的實(shí)例,代表一個(gè)具體的可執(zhí)行的調(diào)度程序,Job 是這個(gè)可執(zhí)行程調(diào)度程序所要執(zhí)行的內(nèi)容,另外 JobDetail 還包含了這個(gè)任務(wù)調(diào)度的方案和策略。

Trigger

代表一個(gè)調(diào)度參數(shù)的配置,什么時(shí)候去調(diào)。

1>  SimpleTrigger:在某個(gè)時(shí)間段內(nèi)實(shí)現(xiàn)定時(shí)任務(wù)的重復(fù)執(zhí)行。

參數(shù):startTime(開始時(shí)間)、endTime(結(jié)束時(shí)間)、repeatCount(重復(fù)數(shù)次)、repeatInterval(重復(fù)執(zhí)行間隔)

2>  CronTrigger:基于日歷的概念執(zhí)行計(jì)劃,這個(gè)trigger是最常用的。

參數(shù):startTime(開始時(shí)間)、endTime(結(jié)束時(shí)間)、cronExpression(定時(shí)表達(dá)式)、timeZone(時(shí)區(qū),默認(rèn)獲取jvm所在時(shí)區(qū))

Scheduler

代表一個(gè)調(diào)度容器,一個(gè)調(diào)度容器中可以注冊(cè)多個(gè) JobDetail 和 Trigger。當(dāng) Trigger 與 JobDetail 組合,就可以被 Scheduler 容器調(diào)度了。

Calendar

是一些日歷特定時(shí)間的集合。一個(gè)Trigger可以和多個(gè)calendar關(guān)聯(lián),可以通過(guò)calendar在指定時(shí)間不執(zhí)行任務(wù)。

示例:服務(wù)啟動(dòng)5秒后執(zhí)行,任務(wù)間隔2秒,服務(wù)啟動(dòng)15秒后關(guān)閉

依賴

<dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
</dependency>

任務(wù)調(diào)度

@Component
//SpringBoot服務(wù)啟動(dòng)執(zhí)行
public class CronScheduler implements CommandLineRunner {
 
    @Override
    public void run(String... args) throws Exception {
        JobDetail build = JobBuilder.newJob(QuartzJob.class)
                .withIdentity("myJob", "group1")
                .build();
        Date date = new Date();
        long startTime = date.getTime() + 5000;
        long endTime = date.getTime() + 15000;
        CronTrigger c = TriggerBuilder.newTrigger()
                .startAt(new Date(startTime))
                .endAt(new Date(endTime))
                .withIdentity("CronTrigger1", "t1")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //設(shè)置調(diào)度的job和trigger
        scheduler.scheduleJob(build, c);
        //開啟調(diào)度
        scheduler.start();
        //暫停,可以重新啟動(dòng)
        //scheduler.standby();
        //停止調(diào)度程序觸發(fā)觸發(fā)器,并清除與調(diào)度程序關(guān)聯(lián)的所有資源
        //scheduler.shushutdown();
    }
    
}

具體執(zhí)行的任務(wù)

public class QuartzJob implements Job {
 
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println(new Date());
    }
 
}

到此這篇關(guān)于springboot實(shí)現(xiàn)定時(shí)任務(wù)的四種方式小結(jié)的文章就介紹到這了,更多相關(guān)springboot 定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java double類型相加精度問(wèn)題的解決

    java double類型相加精度問(wèn)題的解決

    這篇文章主要介紹了java double類型相加精度問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Spring的@RequestParam對(duì)象綁定方式

    Spring的@RequestParam對(duì)象綁定方式

    這篇文章主要介紹了Spring的@RequestParam對(duì)象綁定方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring Aop 如何獲取參數(shù)名參數(shù)值

    Spring Aop 如何獲取參數(shù)名參數(shù)值

    這篇文章主要介紹了Spring Aop 如何獲取參數(shù)名參數(shù)值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java詳細(xì)講解異常Exception的處理

    Java詳細(xì)講解異常Exception的處理

    異常就是不正常,比如當(dāng)我們身體出現(xiàn)了異常我們會(huì)根據(jù)身體情況選擇喝開水、吃藥、看病、等?異常處理方法。?java異常處理機(jī)制是我們java語(yǔ)言使用異常處理機(jī)制為程序提供了錯(cuò)誤處理的能力,程序出現(xiàn)的錯(cuò)誤,程序可以安全的退出,以保證程序正常的運(yùn)行等
    2022-06-06
  • 利用openoffice+jodconverter-code-3.0-bate4實(shí)現(xiàn)ppt轉(zhuǎn)圖片

    利用openoffice+jodconverter-code-3.0-bate4實(shí)現(xiàn)ppt轉(zhuǎn)圖片

    這篇文章主要為大家詳細(xì)介紹了利用openoffice+jodconverter-code-3.0-bate4實(shí)現(xiàn)ppt轉(zhuǎn)圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • 詳解Java目錄操作與文件操作教程

    詳解Java目錄操作與文件操作教程

    本章具體介紹了目錄操作、文件操作的基本使用方法和常用函數(shù),圖解穿插代碼實(shí)現(xiàn),感興趣的朋友來(lái)看看吧
    2022-03-03
  • JAVA 16位ID生成工具類含16位不重復(fù)的隨機(jī)數(shù)數(shù)字+大小寫

    JAVA 16位ID生成工具類含16位不重復(fù)的隨機(jī)數(shù)數(shù)字+大小寫

    這篇文章主要介紹了JAVA 16位ID生成工具類含16位不重復(fù)的隨機(jī)數(shù)數(shù)字+大小寫,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • springboot @ComponentScan注解原理解析

    springboot @ComponentScan注解原理解析

    這篇文章主要介紹了springboot @ComponentScan注解原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot 中使用RabbtiMq?詳解

    SpringBoot 中使用RabbtiMq?詳解

    這篇文章主要介紹了SpringBoot 中使用RabbtiMq詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • java中的分布式事務(wù)解決方式

    java中的分布式事務(wù)解決方式

    分布式事務(wù)是分布式系統(tǒng)中確保數(shù)據(jù)一致性的重要機(jī)制,它涉及多個(gè)數(shù)據(jù)源或參與者,要么所有操作全部成功,要么全部失敗,常見的解決方案包括2PC(兩階段提交協(xié)議)、3PC(三階段提交協(xié)議)和TCC(Try-Confirm-Cancel),2PC雖然簡(jiǎn)單但存在單點(diǎn)故障等問(wèn)題
    2024-09-09

最新評(píng)論