學習springBoot(12)定時任務

傳統定時任務實現的幾種方式:java

Timer:這是java自帶的java.util.Timer類,這個類容許你調度一個java.util.TimerTask任務。使用這種方式可讓你的程序按照某一個頻度執行,但不能在指定時間運行。通常用的較少。

ScheduledExecutorService:也jdk自帶的一個類;是基於線程池設計的定時任務類,每一個調度任務都會分配到線程池中的一個線程去執行,也就是說,任務是併發執行,互不影響。

Spring Task:Spring3.0之後自帶的task,能夠將它當作一個輕量級的Quartz,並且使用起來比Quartz簡單許多。

Quartz:這是一個功能比較強大的的調度器,可讓你的程序在指定時間執行,也能夠按照某一個頻度執行,配置起來稍顯複雜。
複製代碼

在SpringBoot項目中,咱們能夠很簡單的使用註解(@Scheduled)來實現定時任務express

首先了解一下@Scheduled這個註解bash

@Scheduled接受兩種定時的設置:

一種是cornexpression。

一種是Rate/Delay表達式(毫秒值):

    @Scheduled(fixedRate = 6000):上一次開始執行時間點後每隔6秒執行一次。

    @Scheduled(fixedDelay = 6000):上一次執行完畢時間點以後6秒再執行。

    @Scheduled(initialDelay=1000, fixedRate=6000):第一次延遲1秒後執行,以後按fixedRate的規則每6秒執行一次。


注:

*表示全部值,在分鐘裏表示每一分鐘觸發。在小時,日期,月份等裏面表示每一小時,每一日,每一月。

?表示不指定值。表示不關心當前位置設置的值。 好比不關心是周幾,則周的位置填寫?。  主要是因爲日期跟周是有重複的因此二者必須有一者設置爲?

- 表示區間。小時設置爲10-12表示10,11,12點均會觸發。

,表示多個值。 小時設置成10,12表示10點和12點會觸發。

/ 表示遞增觸發。 5/15表示從第5秒開始,每隔15秒觸發。

L 表示最後的意思。 日上表示最後一天。星期上表示星期六或7。 L前加數據,表示該數據的最後一個。

星期上設置6L表示最後一個星期五。  6表示星期五

W表示離指定日期最近的工做日觸發。15W離該月15號最近的工做日觸發。

#表示每個月的第幾個周幾。 6#3表示該月的第三個週五。

 

示例:
"0 0 12 * * ?" 天天中午12點觸發 
"0 15 10 ? * *" 天天上午10:15觸發 
"0 15 10 * * ?" 天天上午10:15觸發 
"0 15 10 * * ? *" 天天上午10:15觸發 
"0 15 10 * * ? 2005" 2005年的天天上午10:15觸發 
"0 * 14 * * ?" 在天天下午2點到下午2:59期間的每1分鐘觸發 
"0 0/5 14 * * ?" 在天天下午2點到下午2:55期間的每5分鐘觸發 
"0 0/5 14,18 * * ?" 在天天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發 
"0 0-5 14 * * ?" 在天天下午2點到下午2:05期間的每1分鐘觸發 
"0 10,44 14 ? 3 WED" 每一年三月的星期三的下午2:10和2:44觸發 
"0 15 10 ? * MON-FRI" 週一至週五的上午10:15觸發 
"0 15 10 15 * ?" 每個月15日上午10:15觸發 
"0 15 10 L * ?" 每個月最後一日的上午10:15觸發 
"0 15 10 ? * 6L" 每個月的最後一個星期五上午10:15觸發 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每個月的最後一個星期五上午10:15觸發 
"0 15 10 ? * 6#3" 每個月的第三個星期五上午10:15觸發 
天天早上6點     0 6 * * *     每兩個小時     0 */2 * * * 
晚上11點到早上8點之間每兩個小時,早上八點    0 23-7/2,8 * * * 
每月的4號和每一個禮拜的禮拜一到禮拜三的早上11點     0 11 4 * 1-3 
1月1日早上4點     0 4 1 1 *
 
複製代碼

在線Cron表達式生成器: cron.qqe2.com/多線程

在主類上使用@EnableScheduling註解開啓對定時任務的支持併發

@Component
public class ScheduledTest {
    private static Logger logger = LoggerFactory.getLogger(ScheduledTest.class);

    @Scheduled(cron = "0/5 * * * * *")
    public void scheduled(){
        logger.info("=====>>>>>cron執行-{}",DateUtils.getCurrentDateMillTime());
    }
    @Scheduled(fixedRate = 5000)
    public void scheduled1() {
        logger.info("=====>>>>>fixedRate執行-{}", DateUtils.getCurrentDateMillTime());
    }
    @Scheduled(fixedDelay = 5000)
    public void scheduled2() {
        logger.info("=====>>>>>fixedDelay執行-{}",DateUtils.getCurrentDateMillTime());
    }
}


複製代碼

重啓項目發現後臺已經有任務在定時執行,時間間隔5秒異步

三個定時任務都已經執行,而且使同一個線程中串行執行,若是隻有一個定時任務,這樣作確定沒問題,當定時任務增多,若是一個任務卡死,會致使其餘任務也沒法執行,這時候就要使用多線程執行ui

建立AsyncConfig類:spa

@Configuration
@EnableAsync //開啓異步事件的支持
public class AsyncConfig {
    @Value("${corePoolSize}")
    private int corePoolSize;

    @Value("${maxPoolSize}")
    private int maxPoolSize;

    @Value("${queueCapacity}")
    private int queueCapacity;

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}
複製代碼

相應配置文件:線程

#定時任務配置
corePoolSize: 10
maxPoolSize: 200
queueCapacity: 10
複製代碼

最後,在定時任務的類或者方法上添加@Async 。最後重啓項目,每個任務都是在不一樣的線程中,相互之間不影響設計

相關文章
相關標籤/搜索