Java實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解_第1頁
Java實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解_第2頁
Java實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解_第3頁
Java實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解_第4頁
Java實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第Java實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解目錄前言定時(shí)任務(wù)是什么定時(shí)任務(wù)的有哪些是實(shí)現(xiàn)方式純手寫單線程循環(huán)Timer和它的小伙伴ScheduledExecutorServiceSpring提供的定時(shí)任務(wù)總結(jié)

前言

學(xué)過定時(shí)任務(wù),但是我忘了,忘得一干二凈,害怕,一直聽別人說:

你寫一個(gè)定時(shí)任務(wù)就好了。

寫個(gè)定時(shí)任務(wù)讓他去爬取就行了。

我不會(huì),所以現(xiàn)在得補(bǔ)回來了,欠下的終究要還的,/(ㄒoㄒ)/~~

定時(shí)任務(wù)是什么

大家都用過鬧鐘,鬧鐘可以說是一種定時(shí)任務(wù)。

比如我們?cè)O(shè)定了周一到周五早上7點(diǎn)半的時(shí)間響鈴,那么鬧鐘就會(huì)在周一到周五的早上7點(diǎn)半進(jìn)行響鈴,這種就是定時(shí)的任務(wù)。時(shí)間定在周一到周五的早上7點(diǎn)半,任務(wù)就是響鈴。

那么,在Java中,如何實(shí)現(xiàn)這樣的功能呢?即如何實(shí)現(xiàn)定時(shí)任務(wù)呢?

定時(shí)任務(wù)的有哪些是實(shí)現(xiàn)方式

說明:@Slf4j注解來源于Lombok,需要引入Lombok依賴

純手寫單線程循環(huán)

單線程,寫一個(gè)死循環(huán),通過線程的睡眠(等待)完成定時(shí)任務(wù):

@Slf4j

publicclassThreadTaskDemo{

publicstaticvoidmain(String[]args){

timer1();

publicstaticvoidtimer1(){

newThread(()-{

while(true){

("當(dāng)前時(shí)間{}",LocalDateTime.now());

try{

//每個(gè)1秒執(zhí)行一次

Thread.sleep(1000);

}catch(InterruptedExceptione){

e.printStackTrace();

}).start();

控制臺(tái)輸出:

14:02:35.893[Thread-0]INFOcn.god23bin.demo.timer.ThreadTaskDemo-當(dāng)前時(shí)間2025-10-25T14:02:35.892

14:02:36.904[Thread-0]INFOcn.god23bin.demo.timer.ThreadTaskDemo-當(dāng)前時(shí)間2025-10-25T14:02:36.904

14:02:37.907[Thread-0]INFOcn.god23bin.demo.timer.ThreadTaskDemo-當(dāng)前時(shí)間2025-10-25T14:02:37.907

可以看到每秒執(zhí)行一次,成功實(shí)現(xiàn)了定時(shí)任務(wù)。

Timer和它的小伙伴

在java.util包下,有這么3個(gè)東西,分別是Timer類、TimerTask接口、TimerThread類,這3個(gè)東西就可以幫我們實(shí)現(xiàn)定時(shí)任務(wù)。

Timer有這么2個(gè)方法(當(dāng)然不止這兩個(gè),還有4個(gè)相關(guān)的):

//延遲delay秒后執(zhí)行task任務(wù)

publicvoidschedule(TimerTasktask,longdelay);

//延遲delay秒后,以period間隔時(shí)間執(zhí)行task任務(wù)

publicvoidschedule(TimerTasktask,longdelay,longperiod);

TimerTask有個(gè)run()抽象方法,那我們可以實(shí)現(xiàn)這個(gè)抽象方法作為我們的任務(wù)邏輯,由于TimerTask是接口,需要一個(gè)類實(shí)現(xiàn)它,那我們下面就用匿名內(nèi)部類的方式來實(shí)現(xiàn)這個(gè)接口。代碼如下:

@Slf4j

publicclassTimerDemo{

publicstaticvoidmain(String[]args){

timer1();

publicstaticvoidtimer1(){

//單線程

Timertimer=newTimer();

("1秒后執(zhí)行任務(wù)A,A完成后,等待1秒開始定時(shí)執(zhí)行任務(wù)B,當(dāng)前時(shí)間{}",LocalDateTime.now());

//1秒后執(zhí)行

timer.schedule(newTimerTask(){

@Override

publicvoidrun(){

("任務(wù)A當(dāng)前時(shí)間{}",LocalDateTime.now());

},1000);//這里1000,就是代表延遲1000毫秒后再執(zhí)行

//每隔2秒執(zhí)行一次這個(gè)任務(wù)

timer.schedule(newTimerTask(){

@Override

publicvoidrun(){

("定時(shí)任務(wù)B當(dāng)前時(shí)間{}",LocalDateTime.now());

},1000,2000);//1000同理,2000即執(zhí)行完本次任務(wù)后,隔2000毫秒后再一次執(zhí)行,達(dá)到定時(shí)任務(wù)的效果

控制臺(tái)輸出:

14:09:37.416[main]INFOcn.god23bin.demo.timer.TimerDemo-1秒后執(zhí)行任務(wù)A,A完成后,等待1秒開始定時(shí)執(zhí)行任務(wù)B,當(dāng)前時(shí)間2025-10-25T14:09:37.415

14:09:38.428[Timer-0]INFOcn.god23bin.demo.timer.TimerDemo-任務(wù)A當(dāng)前時(shí)間2025-10-25T14:09:38.428

14:09:38.428[Timer-0]INFOcn.god23bin.demo.timer.TimerDemo-定時(shí)任務(wù)B當(dāng)前時(shí)間2025-10-25T14:09:38.428

14:09:40.443[Timer-0]INFOcn.god23bin.demo.timer.TimerDemo-定時(shí)任務(wù)B當(dāng)前時(shí)間2025-10-25T14:09:40.443

14:09:42.457[Timer-0]INFOcn.god23bin.demo.timer.TimerDemo-定時(shí)任務(wù)B當(dāng)前時(shí)間2025-10-25T14:09:42.457

從控制臺(tái)輸出的時(shí)間可以看到,任務(wù)A是只執(zhí)行了一次,因?yàn)槲覀儧]有傳遞period參數(shù)給schedule()方法。而任務(wù)B是一個(gè)定時(shí)任務(wù),因?yàn)閭鬟f了period參數(shù),period參數(shù)為2000,即2000毫秒。

所以,任務(wù)B會(huì)每隔2秒執(zhí)行一次。到這里,我們通過Timer實(shí)現(xiàn)了定時(shí)任務(wù)。下面看看基于多線程的ScheduledExecutorService接口。

ScheduledExecutorService

ScheduledExecutorService接口位于java.util.concurrent包中,是繼承ExecutorService接口的。

這個(gè)接口有4個(gè)抽象方法(先了解一下):

publicScheduledFutureschedule(Runnablecommand,longdelay,TimeUnitunit);

publicVScheduledFutureVschedule(CallableVcallable,longdelay,TimeUnitunit);

publicScheduledFuturescheduleAtFixedRate(Runnablecommand,longinitialDelay,longperiod,TimeUnitunit);

publicScheduledFuturescheduleWithFixedDelay(Runnablecommand,longinitialDelay,longdelay,TimeUnitunit);

從上面的抽象方法可以看到,第一個(gè)參數(shù)是Runnable接口或Callable接口,這里就是寫任務(wù)邏輯的,后面的delay也和之前的意思一樣,延遲多少時(shí)間才開始執(zhí)行這個(gè)定時(shí)任務(wù),unit主要是指定long參數(shù)的時(shí)間單位。period也是一樣的意思,間隔多少秒(周期)才執(zhí)行下一次的任務(wù)。

ExecutorService接口表述了異步執(zhí)行的機(jī)制,并且可以讓任務(wù)在后臺(tái)執(zhí)行。ExecutorService接口的實(shí)現(xiàn)類有我們知道的ThreadPoolExecutor(不知道的話,現(xiàn)在就知道啦)。

基本使用

那我們?nèi)绾潍@取ScheduledExecutorService的實(shí)現(xiàn)類?如何使用它實(shí)現(xiàn)定時(shí)任務(wù)?

可以通過Executors.newSingleThreadScheduledExecutor()獲取其實(shí)現(xiàn)類,然后調(diào)用schedule()方法實(shí)現(xiàn)定時(shí)任務(wù)。

現(xiàn)在先看一下,如何使用:

@Slf4j

publicclassScheduledExecutorServiceDemo{

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{

testScheduledExecutorService();

publicstaticvoidtestScheduledExecutorService()throwsExecutionException,InterruptedException{

ScheduledExecutorServicescheduledExecutorService=Executors.newSingleThreadScheduledExecutor();

("2秒后開始執(zhí)行任務(wù),此刻時(shí)間---{}",LocalDateTime.now());

ScheduledFuturefuture=scheduledExecutorService.schedule(()-{

("任務(wù)開始---{}",LocalDateTime.now());

try{

Thread.sleep(2000);

}catch(InterruptedExceptione){

e.printStackTrace();

("任務(wù)結(jié)束---{}",LocalDateTime.now());

return"ok";

},2000,TimeUnit.MILLISECONDS);//延遲2秒后執(zhí)行

("任務(wù)執(zhí)行后future{},時(shí)間{}",future.get(),LocalDateTime.now());

控制臺(tái)輸出:

14:15:44.510[main]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-2秒后開始執(zhí)行任務(wù),此刻時(shí)間---2025-10-25T14:15:44.509

14:15:46.524[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)開始---2025-10-25T14:15:46.524

14:15:48.537[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)結(jié)束---2025-10-25T14:15:48.537

14:15:48.538[main]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)執(zhí)行后futureok,時(shí)間2025-10-25T14:15:48.538

很明顯,這里不是一個(gè)定時(shí)任務(wù),因?yàn)橹粓?zhí)行了一次就結(jié)束了,所以我們需要調(diào)用兩外兩個(gè)來實(shí)現(xiàn),分別是scheduleAtFixedRate()方法和scheduleWithFixedDelay()方法。

固定頻率觸發(fā)定時(shí)任務(wù)

scheduleAtFixedRate()方法,可以固定多久就觸發(fā)一次任務(wù)。下面我們寫一個(gè)延遲2秒后開始執(zhí)行任務(wù),經(jīng)過5秒后再執(zhí)行下一次的任務(wù)的代碼:

@Slf4j

publicclassScheduledExecutorServiceDemo{

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{

testFixedRate();

publicstaticvoidtestFixedRate(){

ScheduledExecutorServicescheduledExecutorService=Executors.newSingleThreadScheduledExecutor();

("2秒后開始執(zhí)行任務(wù),此刻時(shí)間---{}",LocalDateTime.now());

//固定頻率(每隔5秒)開始執(zhí)行一個(gè)任務(wù)

scheduledExecutorService.scheduleAtFixedRate(()-{

("任務(wù)開始---{}",LocalDateTime.now());

try{

Thread.sleep(2000);

}catch(InterruptedExceptione){

e.printStackTrace();

("任務(wù)結(jié)束---{}",LocalDateTime.now());

},2000,5000,TimeUnit.MILLISECONDS);

通過Thread.sleep(2000)模擬任務(wù)執(zhí)行了2秒的時(shí)間,控制臺(tái)輸出如下:

14:17:15.081[main]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-2秒后開始執(zhí)行任務(wù),此刻時(shí)間---2025-10-25T14:17:15.079

14:17:17.094[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)開始---2025-10-25T14:17:17.094

14:17:19.109[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)結(jié)束---2025-10-25T14:17:19.109

14:17:22.094[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)開始---2025-10-25T14:17:22.094

14:17:24.106[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)結(jié)束---2025-10-25T14:17:24.106

14:17:27.090[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)開始---2025-10-25T14:17:27.090

14:17:29.099[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)結(jié)束---2025-10-25T14:17:29.099

可以看到,第一次執(zhí)行的時(shí)間是14:17:17,即第17秒,下一次執(zhí)行的時(shí)間是14:17:22,即第22秒,這個(gè)過程經(jīng)過了5秒鐘,這就是scheduleAtFixedRate()方法的效果。

固定延遲觸發(fā)定時(shí)任務(wù)

scheduleWithFixedDelay()方法,可以固定任務(wù)完成后延遲多久才執(zhí)行下一次任務(wù)。下面我們寫一個(gè)延遲1秒后開始執(zhí)行定時(shí)任務(wù),當(dāng)任務(wù)完成后,延遲4秒再執(zhí)行下一次任務(wù)。代碼如下:

@Slf4j

publicclassScheduledExecutorServiceDemo{

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{

testFixedDelay();

publicstaticvoidtestFixedDelay(){

ScheduledExecutorServicescheduledExecutorService=Executors.newSingleThreadScheduledExecutor();

("1秒后開始執(zhí)行任務(wù),此刻時(shí)間---{}",LocalDateTime.now());

//任務(wù)完成后間隔4秒開始執(zhí)行下一次任務(wù)

scheduledExecutorService.scheduleWithFixedDelay(()-{

("任務(wù)開始---{}",LocalDateTime.now());

try{

Thread.sleep(2000);

}catch(InterruptedExceptione){

e.printStackTrace();

("任務(wù)結(jié)束---{}",LocalDateTime.now());

},1000,4000,TimeUnit.MILLISECONDS);

通過Thread.sleep(2000)模擬任務(wù)執(zhí)行了2秒的時(shí)間,控制臺(tái)輸出如下:

14:20:31.352[main]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-1秒后開始執(zhí)行任務(wù),此刻時(shí)間---2025-10-25T14:20:31.351

14:20:32.370[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)開始---2025-10-25T14:20:32.370

14:20:34.371[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)結(jié)束---2025-10-25T14:20:34.371

14:20:38.379[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)開始---2025-10-25T14:20:38.379

14:20:40.381[pool-1-thread-1]INFOcn.god23bin.demo.timer.ScheduledExecutorServiceDemo-任務(wù)結(jié)束---2025-10-25T14:20:40.381

可以看到,第一次任務(wù)結(jié)束的時(shí)間是14:20:34,即第34秒,下一次執(zhí)行的時(shí)間是14:17:38,即第38秒,這個(gè)過程經(jīng)過了4秒鐘,這就是scheduleWithFixedDelay()方法的效果。

以上就是ScheduledExecutorService實(shí)現(xiàn)的定時(shí)任務(wù),接下來看看Spring提供的。

Spring提供的定時(shí)任務(wù)

Spring提供了@EnableScheduling和@Scheduled這兩個(gè)注解來實(shí)現(xiàn)定時(shí)任務(wù)。

我們可以編寫一個(gè)類,加上@Component讓Spring來管理這個(gè)Bean(當(dāng)然,也可以用@Configuration注解),加上@EnableScheduling表明該Bean具有可開啟定時(shí)任務(wù)的功能。

在這個(gè)普通的類中編寫方法,你可以讓你寫的方法成為一個(gè)定時(shí)任務(wù),只需在方法上加上@Scheduled注解就可以了,就是這么簡(jiǎn)單!

還有一個(gè)就是cron表達(dá)式需要學(xué)習(xí),這個(gè)表達(dá)式可以表明這個(gè)方法何時(shí)執(zhí)行。

下面是一個(gè)簡(jiǎn)單的定時(shí)任務(wù):

@Slf4j

@Component

@EnableScheduling

publicclassTaskDemo{

@Scheduled(cron="*/1****")

publicvoidprintTime()throwsInterruptedException{

("此刻時(shí)間{}",LocalDateTime.now());

cron表達(dá)式有6位,是必須的,從左到右分別表示:秒、分、時(shí)、日、月、周。

當(dāng)然也有可能是7位,那么最后一位就是年(一般省略不寫):秒、分、時(shí)、日、月、周、年。

取值說明:正常認(rèn)識(shí),秒分都是0-59,時(shí)則是0-23,日則是1-31,月則是1-12,周則是1-7。年則只有1970-2099

每一位都可以用數(shù)字表示,當(dāng)然還可以用一些特殊字符表示,比如上面出現(xiàn)的*/1****,第1位的*/1表示任意秒每隔1秒,第2位的*表示任意分鐘,以此類推。

詳細(xì)可參考這里:Cron表達(dá)式的詳細(xì)用法

Cron生成工具:/

上面的代碼運(yùn)行之后,控制臺(tái)輸出:

2025-10-2514:26:22.013INFO18304---[scheduling-1]cn.god23bin.demo.task.TaskDemo:此刻時(shí)間2025-10-25T14:26:22.013

2025-10-2514:26:23.010INFO18304---[scheduling-1]cn.god23bin.demo.task.TaskDemo:此刻時(shí)間2025-10-25T14:26:23.010

2025-10-2514:26:24.011INFO18304---[scheduling-1]cn.god23bin.demo.task.TaskDemo:此刻時(shí)間2025-10-25T14:26:24.011

2025-10-2514:26:25.011INFO18304---[scheduling-1]cn.god23bin.demo.task.TaskDemo:此刻時(shí)間2025-10-25T14:26:25.011

可以看到,確實(shí)是每隔1秒執(zhí)行一次printTime()這個(gè)定時(shí)任務(wù)。

@Scheduled的另外兩個(gè)屬性

@Scheduled注解除了cron這個(gè)屬性外,還有fixedRate屬性和fixedDelay屬性,同理,就是固定頻率觸發(fā)定時(shí)任務(wù)和固定延遲觸發(fā)定時(shí)任務(wù)

fixedRate

@Slf4j

@Component

@EnableScheduling

publicclassTaskDemo{

*當(dāng)前任務(wù)執(zhí)行到下一個(gè)任務(wù)開始的時(shí)間(固定頻率開始執(zhí)行一個(gè)任務(wù),每5秒執(zhí)行),都是單線程處理的

@Scheduled(fixedRate=5000)

publicvoidprintTime1()throwsInterruptedException{

("任務(wù)開始-------{}",LocalDateTime.now());

Thread.sleep(1000);

("任務(wù)完成-------{}",LocalDateTime.now());

控制臺(tái)輸出:

2025-10-2514:54:04.824INFO23520---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:54:04.824

2025-10-2514:54:05.833INFO23520---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:54:05.833

2025-10-2514:54:09.834INFO23520---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:54:09.834

2025-10-2514:54:10.843INFO23520---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:54:10.843

當(dāng)然,如果任務(wù)的處理邏輯超過了固定的頻率時(shí)間,比如我們修改下Thread.sleep(1000),模擬成6秒,即Thread.sleep(6000),那么輸出如下:

2025-10-2514:57:04.212INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:57:04.212

2025-10-2514:57:10.227INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:57:10.227

2025-10-2514:57:10.227INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:57:10.227

2025-10-2514:57:16.241INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:57:16.241

2025-10-2514:57:16.242INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:57:16.242

2025-10-2514:57:22.243INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:57:22.243

2025-10-2514:57:22.243INFO9324---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:57:22.243

可以發(fā)現(xiàn),當(dāng)前任務(wù)一完成就會(huì)立刻執(zhí)行下一次任務(wù),這就是當(dāng)任務(wù)的處理邏輯超過了固定的頻率時(shí)間會(huì)出現(xiàn)的情況。

fixedDelay

@Slf4j

@Component

@EnableScheduling

publicclassTaskDemo{

*執(zhí)行完成后間隔2秒執(zhí)行下一次

@Scheduled(fixedDelay=2000)

publicvoidprintTime2()throwsInterruptedException{

("任務(wù)開始-------{}",LocalDateTime.now());

Thread.sleep(4000);

("任務(wù)完成-------{}",LocalDateTime.now());

控制臺(tái)輸出:

2025-10-2514:55:50.973INFO22128---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:55:50.973

2025-10-2514:55:54.977INFO22128---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:55:54.977

2025-10-2514:55:56.987INFO22128---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:55:56.987

2025-10-2514:56:01.001INFO22128---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)完成-------2025-10-25T14:56:01.001

2025-10-2514:56:03.012INFO22128---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)開始-------2025-10-25T14:56:03.012

多個(gè)定時(shí)任務(wù)的執(zhí)行

同步

如果我們寫多個(gè)定時(shí)任務(wù),那么它們只會(huì)同步執(zhí)行,如下:

@Slf4j

@Component

@EnableScheduling

publicclassTaskDemo{

@Scheduled(fixedRate=2000)

publicvoidprintTime3()throwsInterruptedException{

("任務(wù)A開始-------{}",LocalDateTime.now());

Thread.sleep(2000);

("任務(wù)A完成-------{}",LocalDateTime.now());

@Scheduled(fixedDelay=2000)

publicvoidprintTime4()throwsInterruptedException{

("任務(wù)B開始-------{}",LocalDateTime.now());

Thread.sleep(2000);

("任務(wù)B完成-------{}",LocalDateTime.now());

控制臺(tái)輸出:

2025-10-2514:59:14.279INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A開始-------2025-10-25T14:59:14.279

2025-10-2514:59:16.283INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A完成-------2025-10-25T14:59:16.283

2025-10-2514:59:16.283INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)B開始-------2025-10-25T14:59:16.283

2025-10-2514:59:18.288INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)B完成-------2025-10-25T14:59:18.288

2025-10-2514:59:18.288INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A開始-------2025-10-25T14:59:18.288

2025-10-2514:59:20.301INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A完成-------2025-10-25T14:59:20.301

2025-10-2514:59:20.301INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A開始-------2025-10-25T14:59:20.301

2025-10-2514:59:22.307INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A完成-------2025-10-25T14:59:22.307

2025-10-2514:59:22.307INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A開始-------2025-10-25T14:59:22.307

2025-10-2514:59:24.323INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A完成-------2025-10-25T14:59:24.323

2025-10-2514:59:24.323INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)B開始-------2025-10-25T14:59:24.323

2025-10-2514:59:26.337INFO21588---[scheduling-1]cn.god23bin.demo.task.TaskDemo:任務(wù)B完成-------2025-10-25T14:59:26.337

可以看到,只有某一個(gè)任務(wù)完成后,下一個(gè)任務(wù)才會(huì)執(zhí)行。

如果想要異步,如何異步呢?

異步

很簡(jiǎn)單,使用@EnableAsync和@Async這兩個(gè)注解就可以了,如下:

@Slf4j

@Component

@EnableScheduling

@EnableAsync

publicclassTaskDemo{

@Async

@Scheduled(fixedRate=2000)

publicvoidprintTime3()throwsInterruptedException{

("任務(wù)A開始-------{}",LocalDateTime.now());

Thread.sleep(2000);

("任務(wù)A完成-------{}",LocalDateTime.now());

@Async

@Scheduled(fixedDelay=2000)

publicvoidprintTime4()throwsInterruptedException{

("任務(wù)B開始-------{}",LocalDateTime.now());

Thread.sleep(2000);

("任務(wù)B完成-------{}",LocalDateTime.now());

控制臺(tái)輸出:

2025-10-2515:04:05.833INFO15604---[task-1]cn.god23bin.demo.task.TaskDemo:任務(wù)A開始-------2025-10-25T15:04:05.8

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論