上一節(jié),我們通過自己啟動一個線程來執(zhí)行定時任務(wù),其實我們還有許多方便執(zhí)行定時任務(wù)的方法。quartz是非常出名的一個定時任務(wù)框架,spring也提供了一個定時任務(wù)框架,兩者使用方法基本一樣,但是spring的定時任務(wù)框架其實是quartz的簡化版,他不支持任務(wù)的持久化,不支持分布式。這里,我們簡單介紹怎么啟用spring的定時任務(wù)框架。
1、開啟注解

使用@EnableScheduling來開啟注解。
2、Fixed
我們注釋掉之前CmsController里面的”定時任務(wù)“

新建一個CmsTimer類

使用@Scheduled注解方法,fixedRate表示每隔多少毫秒執(zhí)行一次。我們還可以通過設(shè)置initialDelay來控制第一次執(zhí)行的時間,如沒設(shè)置initialDelay的時候,初始化完就會馬上執(zhí)行一次,如果我們想1分鐘后再執(zhí)行第一次任務(wù),就可以設(shè)置initialDelay=60*1000。fixedDelay與fixedRate的區(qū)別是,前者是在任務(wù)執(zhí)行完后延遲多久,后者是在任務(wù)開始后延遲多久。
3、cron表達式
@Scheduled(cron = "0 * * * * ?")
上面的cron表達式,表示每分鐘執(zhí)行一次,第一次執(zhí)行是秒鐘置0的時候。cron表達式具體的用法大家自行查找。
4、多任務(wù)
如果我們代碼中定義了多個定時任務(wù),恰好幾個任務(wù)會同時執(zhí)行,會發(fā)現(xiàn)任務(wù)會有延遲或丟失的可能,這是因為,spring提供的定時任務(wù)其實底層就是ScheduledThreadPoolExecutor,默認只有一個任務(wù)線程,一個線程執(zhí)行完當前任務(wù),才能執(zhí)行另外一個任務(wù)。如果碰到任務(wù)執(zhí)行不過來的情況,我們可以加大線程池,通過spring.task.scheduling.pool.size配置。

我們還可以配置異步線程,spring將默認開啟8個線程來執(zhí)行異步操作。
5、總結(jié)
這節(jié)我們講了怎么在spring里面快速實現(xiàn)定時任務(wù),文章開頭我們說了,這種方式不支持任務(wù)持久化,不支持分布式,如果需要這兩個特性,我們可以使用quartz,或者自己在spring定時任務(wù)上做一點點開發(fā)工作。例如,如果要支持集群部署,有時我們可以在配置文件里面增加一個變量,配置是否開啟定時任務(wù),這樣就會只有一臺機器跑定時任務(wù),這也是我們常見的做法。如果要真正的分布式,我們也可以通過redis加鎖,或者zookeeper的方式實現(xiàn)。
代碼:
https://github.com/www15119258/springboot-study/tree/branch35