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

SpringBoot中的定時調度服務使用詳解

 更新時間:2026年04月03日 08:56:17   作者:志哥聊技術  
本文介紹了SpringBoot中定時任務的實踐應用,包括pom包配置、啟動類啟用定時調度、創(chuàng)建定時任務、異步執(zhí)行定時任務、自定義任務線程池等內容,SpringBoot內置的@Scheduled注解可以滿足大部分業(yè)務需求

一、背景介紹

在實際的業(yè)務開發(fā)過程中,我們經常會需要定時任務來幫助我們完成一些工作,例如每天早上 6 點生成銷售報表、每晚 23 點清理臟數(shù)據等等。

如果你當前使用的是 SpringBoot 來開發(fā)項目,那么完成這些任務會非常容易!

SpringBoot 默認已經幫我們完成了相關定時任務組件的配置,我們只需要添加相應的注解@Scheduled就可以實現(xiàn)任務調度!

二、方案實踐

2.1、pom 包配置

pom包里面只需要引入Spring Boot Starter包即可!

<dependencies>
    <!--spring boot核心-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!--spring boot 測試-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2.2、啟動類啟用定時調度

在啟動類上面加上@EnableScheduling即可開啟定時

@SpringBootApplication
@EnableScheduling
public class ScheduleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ScheduleApplication.class, args);
    }
}

2.3、創(chuàng)建定時任務

Spring Scheduler支持四種形式的任務調度!

  • fixedRate:固定速率執(zhí)行,例如每5秒執(zhí)行一次
  • fixedDelay:固定延遲執(zhí)行,例如距離上一次調用成功后2秒執(zhí)行
  • initialDelay:初始延遲任務,例如任務開啟過5秒后再執(zhí)行,之后以固定頻率或者間隔執(zhí)行
  • cron:使用 Cron 表達式執(zhí)行定時任務

2.3.1、固定速率執(zhí)行

你可以通過使用fixedRate參數(shù)以固定時間間隔來執(zhí)行任務,示例如下:

@Component
public class SchedulerTask {

    private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * fixedRate:固定速率執(zhí)行。每5秒執(zhí)行一次。
     */
    @Scheduled(fixedRate = 5000)
    public void runWithFixedRate() {
        log.info("Fixed Rate Task,Current Thread : {},The time is now : {}", Thread.currentThread().getName(), dateFormat.format(new Date()));
    }
}

運行ScheduleApplication主程序,即可看到控制臺輸出效果:

Fixed Rate Task,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:00
Fixed Rate Task,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:10
...

2.3.2、固定延遲執(zhí)行

你可以通過使用fixedDelay參數(shù)來設置上一次任務調用完成與下一次任務調用開始之間的延遲時間,示例如下:

@Component
public class SchedulerTask {

    private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * fixedDelay:固定延遲執(zhí)行。距離上一次調用成功后2秒后再執(zhí)行。
     */
    @Scheduled(fixedDelay = 2000)
    public void runWithFixedDelay() {
        log.info("Fixed Delay Task,Current Thread : {},The time is now : {}", Thread.currentThread().getName(), dateFormat.format(new Date()));
    }
}

控制臺輸出效果:

Fixed Delay Task,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:00
Fixed Delay Task,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:02
...

2.3.3、初始延遲任務

你可以通過使用initialDelay參數(shù)與fixedRate或者fixedDelay搭配使用來實現(xiàn)初始延遲任務調度。

@Component
public class SchedulerTask {

    private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * initialDelay:初始延遲。任務的第一次執(zhí)行將延遲5秒,然后將以5秒的固定間隔執(zhí)行。
     */
    @Scheduled(initialDelay = 5000, fixedRate = 5000)
    public void reportCurrentTimeWithInitialDelay() {
        log.info("Fixed Rate Task with Initial Delay,Current Thread : {},The time is now : {}", Thread.currentThread().getName(), dateFormat.format(new Date()));
    }
}

控制臺輸出效果:

Fixed Rate Task with Initial Delay,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:05
Fixed Rate Task with Initial Delay,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:10
...

2.3.4、使用 Cron 表達式

Spring Scheduler同樣支持Cron表達式,如果以上簡單參數(shù)都不能滿足現(xiàn)有的需求,可以使用 cron 表達式來定時執(zhí)行任務。

關于cron表達式的具體用法,可以點擊參考這里: https://cron.qqe2.com/

@Component
public class SchedulerTask {

    private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * cron:使用Cron表達式。每6秒中執(zhí)行一次
     */
    @Scheduled(cron = "*/6 * * * * ?")
    public void reportCurrentTimeWithCronExpression() {
        log.info("Cron Expression,Current Thread : {},The time is now : {}", Thread.currentThread().getName(), dateFormat.format(new Date()));
    }
}

控制臺輸出效果:

Cron Expression,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:06
Cron Expression,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 11:46:12
...

2.4、異步執(zhí)行定時任務

在介紹異步執(zhí)行定時任務之前,我們先看一個例子!

在下面的示例中,我們創(chuàng)建了一個每隔2秒執(zhí)行一次的定時任務,在任務里面大概需要花費 3 秒鐘,猜猜執(zhí)行結果如何?

@Component
public class AsyncScheduledTask {

    private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTask.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Scheduled(fixedRate = 2000)
    public void runWithFixedDelay() {
        try {
            TimeUnit.SECONDS.sleep(3);
            log.info("Fixed Delay Task, Current Thread : {} : The time is now {}", Thread.currentThread().getName(), dateFormat.format(new Date()));
        } catch (InterruptedException e) {
            log.error("錯誤信息",e);
        }
    }
}

控制臺輸入結果:

Fixed Delay Task, Current Thread : scheduling-1 : The time is now 2020-12-15 17:55:26
Fixed Delay Task, Current Thread : scheduling-1 : The time is now 2020-12-15 17:55:31
Fixed Delay Task, Current Thread : scheduling-1 : The time is now 2020-12-15 17:55:36
Fixed Delay Task, Current Thread : scheduling-1 : The time is now 2020-12-15 17:55:41
...

很清晰的看到,任務調度頻率變成了每隔5秒調度一次!

這是為啥呢?

Current Thread : scheduling-1輸出結果可以很看到,任務執(zhí)行都是同一個線程!默認的情況下,@Scheduled任務都在 Spring 創(chuàng)建的大小為 1 的默認線程池中執(zhí)行!

更直觀的結果是,任務都是串行執(zhí)行!

下面,我們將其改成異步線程來執(zhí)行,看看效果如何?

@Component
@EnableAsync
public class AsyncScheduledTask {

    private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTask.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    @Async
    @Scheduled(fixedDelay = 2000)
    public void runWithFixedDelay() {
        try {
            TimeUnit.SECONDS.sleep(3);
            log.info("Fixed Delay Task, Current Thread : {} : The time is now {}", Thread.currentThread().getName(), dateFormat.format(new Date()));
        } catch (InterruptedException e) {
            log.error("錯誤信息",e);
        }
    }
}

控制臺輸出結果:

Fixed Delay Task, Current Thread : SimpleAsyncTaskExecutor-1 : The time is now 2020-12-15 18:55:26
Fixed Delay Task, Current Thread : SimpleAsyncTaskExecutor-2 : The time is now 2020-12-15 18:55:28
Fixed Delay Task, Current Thread : SimpleAsyncTaskExecutor-3 : The time is now 2020-12-15 18:55:30
...

任務的執(zhí)行頻率不受方法內的時間影響,以并行方式執(zhí)行!

2.5、自定義任務線程池

雖然默認的情況下,@Scheduled任務都在 Spring 創(chuàng)建的大小為 1 的默認線程池中執(zhí)行,但是我們也可以自定義線程池,只需要實現(xiàn)SchedulingConfigurer類即可!

自定義線程池示例如下:

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        //線程池大小為10
        threadPoolTaskScheduler.setPoolSize(10);
        //設置線程名稱前綴
        threadPoolTaskScheduler.setThreadNamePrefix("scheduled-thread-");
        //設置線程池關閉的時候等待所有任務都完成再繼續(xù)銷毀其他的Bean
        threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        //設置線程池中任務的等待時間,如果超過這個時候還沒有銷毀就強制銷毀,以確保應用最后能夠被關閉,而不是阻塞住
        threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
        //這里采用了CallerRunsPolicy策略,當線程池沒有處理能力的時候,該策略會直接在 execute 方法的調用線程中運行被拒絕的任務;如果執(zhí)行程序已關閉,則會丟棄該任務
        threadPoolTaskScheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

我們啟動服務,看看cron任務示例調度效果:

Cron Expression,Current Thread : scheduled-thread-1,The time is now : 2020-12-15 20:46:00
Cron Expression,Current Thread : scheduled-thread-2,The time is now : 2020-12-15 20:46:06
Cron Expression,Current Thread : scheduled-thread-3,The time is now : 2020-12-15 20:46:12
Cron Expression,Current Thread : scheduled-thread-4,The time is now : 2020-12-15 20:46:18
....

當前線程名稱已經被改成自定義scheduled-thread的前綴!

三、總結

本文主要圍繞Spring scheduled應用實踐進行分享,如果是單體應用,使用SpringBoot內置的@scheduled注解可以解決大部分業(yè)務需求,上手非常容易!

項目源代碼地址:spring-boot-example-schedule

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Spring Boot整合ElasticSearch實現(xiàn)多版本兼容的方法詳解

    Spring Boot整合ElasticSearch實現(xiàn)多版本兼容的方法詳解

    簡單說,ElasticSearch(簡稱 ES)是搜索引擎,是結構化數(shù)據的分布式搜索引擎。下面這篇文章主要給大家介紹了關于Spring Boot整合ElasticSearch實現(xiàn)多版本兼容的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧
    2018-05-05
  • Java?agent的入門與demo演示詳解

    Java?agent的入門與demo演示詳解

    Java?Agent?是?Java?1.5?版本之后引?的特性,其主要作?是在class被加載之前對其攔截,這篇文章主要介紹了agent的簡單使用,需要的可以參考下
    2023-05-05
  • java實現(xiàn)ip地址與十進制數(shù)相互轉換

    java實現(xiàn)ip地址與十進制數(shù)相互轉換

    本文介紹在java中IP地址轉換十進制數(shù)及把10進制再轉換成IP地址的方法及實例參考,曬出來和大家分享一下
    2012-12-12
  • SpringBoot項目創(chuàng)建使用+配置文件+日志文件詳解

    SpringBoot項目創(chuàng)建使用+配置文件+日志文件詳解

    Spring的出現(xiàn)是為了簡化 Java 程序開發(fā),而 SpringBoot 的出現(xiàn)是為了簡化 Spring 程序開發(fā),這篇文章主要介紹了SpringBoot項目創(chuàng)建使用+配置文件+日志文件,需要的朋友可以參考下
    2023-02-02
  • 深入了解JVM(Java虛擬機)內存結構

    深入了解JVM(Java虛擬機)內存結構

    Java虛擬機(Java Virtual Machine,JVM)是Java程序的運行環(huán)境,它是一個抽象的計算機模型,通過解釋和執(zhí)行Java字節(jié)碼來運行Java程序,本將大家深入了解JVM(Java虛擬機)內存結構,需要的朋友可以參考下
    2023-08-08
  • 詳解@Autowired(required=false)注入注意的問題

    詳解@Autowired(required=false)注入注意的問題

    這篇文章主要介紹了@Autowired(required=false)注入注意的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Spring@Value使用獲取配置信息為null的操作

    Spring@Value使用獲取配置信息為null的操作

    這篇文章主要介紹了Spring@Value使用獲取配置信息為null的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • SpringBoot+JSON+AJAX+ECharts+Fiddler實現(xiàn)前后端分離開發(fā)可視化

    SpringBoot+JSON+AJAX+ECharts+Fiddler實現(xiàn)前后端分離開發(fā)可視化

    這篇文章主要介紹了SpringBoot+JSON+AJAX+ECharts+Fiddler實現(xiàn)前后端分離開發(fā)可視化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • Python文件高級操作函數(shù)之文件信息獲取與目錄操作

    Python文件高級操作函數(shù)之文件信息獲取與目錄操作

    這篇文章主要介紹了Python文件高級操作函數(shù)之文件信息獲取與目錄操作,在Python中,內置了文件(File)對象。在使用文件對象時,首先需要通過內置的open()方法創(chuàng)建一個文件對象,然后通過該對象提供的方法進行一些基本文件操作,需要的朋友可以參考下
    2023-05-05
  • SpringKafka錯誤處理(重試機制與死信隊列)

    SpringKafka錯誤處理(重試機制與死信隊列)

    Spring Kafka提供了全面的錯誤處理機制,通過靈活的重試策略和死信隊列處理,下面就來介紹一下,具有一定的參考價值,感興趣的可以了解一下
    2025-04-04

最新評論

陇西县| 长宁县| 舞阳县| 通州市| 贡山| 鹤庆县| 确山县| 临西县| 山东省| 靖远县| 高安市| 克山县| 灵璧县| 中西区| 高雄市| 德格县| 萍乡市| 秦安县| 色达县| 聊城市| 扎囊县| 临武县| 景谷| 肥城市| 黎城县| 襄樊市| 兴宁市| 汉川市| 五峰| 江城| 文成县| 邻水| 来安县| 万载县| 三江| 弋阳县| 志丹县| 扶沟县| 哈巴河县| 都昌县| 凭祥市|