SpringBoot:實現定時任務
阿新 • • 發佈:2019-08-22
一、定時任務實現的幾種方式:
Timer
這是java自帶的java.util.Timer類,這個類允許你排程一個java.util.TimerTask任務。使用這種方式可以讓你的程式按照某一個頻度執行,但不能在指定時間執行。一般用的較少。
ScheduledExecutorService
也jdk自帶的一個類;是基於執行緒池設計的定時任務類,每個排程任務都會分配到執行緒池中的一個執行緒去執行,也就是說,任務是併發執行,互不影響。
Spring Task
Spring3.0以後自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多。
Quartz
這是一個功能比較強大的的排程器,可以讓你的程式在指定時間執行,也可以按照某一個頻度執行,配置起來稍顯複雜。
二、基於SpringBoot的定時任務
使用SpringBoot 自帶的定時任務,只需要新增相應的註解就可以實現
2.1 匯入SpringBoot啟動包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
2.2 啟動類啟用定時
在啟動類上面加上@EnableScheduling
即可開啟定時
@SpringBootApplication @EnableScheduling // 開啟定時 public class SpringBootDemoTimeTaskApplication { private static final Logger logger = LoggerFactory.getLogger(SpringBootDemoTimeTaskApplication.class); public static void main(String[] args) { SpringApplication.run(SpringBootDemoTimeTaskApplication.class); logger.info("SpringBootDemoTimeTaskApplication start!"); } }
2.3 建立定時任務實現類SchedulerTask
@Component
public class SchedulerTask {
private static final Logger logger = LoggerFactory.getLogger(SchedulerTask.class);
/**
* @Scheduled(fixedRate = 6000) :上一次開始執行時間點之後6秒再執行
* @Scheduled(fixedDelay = 6000) :上一次執行完畢時間點之後6秒再執行
* @Scheduled(initialDelay=1000, fixedRate=6000) :第一次延遲1秒後執行,之後按fixedRate的規則每6秒執行一次
* @Scheduled(cron=""):詳見cron表示式http://www.pppet.net/
*/
@Scheduled(fixedRate = 5000)
public void scheduled1() {
logger.info("=====>>>>>使用fixedRate執行定時任務");
}
@Scheduled(fixedDelay = 10000)
public void scheduled2() {
logger.info("=====>>>>>使用fixedDelay執行定時任務");
}
@Scheduled(cron="*/6 * * * * ?")
private void scheduled3(){
logger.info("使用cron執行定時任務");
}
}
執行結果:
2019-03-09 17:33:05.681 INFO 7752 --- [ main] c.v.t.SpringBootDemoTimeTaskApplication : SpringBootDemoTimeTaskApplication start!
2019-03-09 17:33:06.002 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : 使用cron執行定時任務
2019-03-09 17:33:10.680 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:12.003 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : 使用cron執行定時任務
2019-03-09 17:33:15.676 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:15.676 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedDelay執行定時任務
2019-03-09 17:33:18.002 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : 使用cron執行定時任務
2019-03-09 17:33:20.677 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:24.002 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : 使用cron執行定時任務
2019-03-09 17:33:25.680 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:25.681 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedDelay執行定時任務
2019-03-09 17:33:30.005 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : 使用cron執行定時任務
2019-03-09 17:33:30.680 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:35.680 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:35.682 INFO 7752 --- [ scheduling-1] cn.van.task.service.SchedulerTask : =====>>>>>使用fixedDelay執行定時任務
2.4 執行時間的配置
在上面的定時任務中,我們在方法上使用@Scheduled
註解來設定任務的執行時間,並且使用三種屬性配置方式:
- fixedRate:定義一個按一定頻率執行的定時任務
- fixedDelay:定義一個按一定頻率執行的定時任務,與上面不同的是,改屬性可以配合initialDelay, 定義該任務延遲執行時間。
- cron:通過表示式來配置任務執行時間--線上cron表示式生成器
三、多執行緒執行定時任務
SpringBoot定時任務預設單執行緒,可以看到三個定時任務都已經執行,並且使同一個執行緒中(
scheduling-1
)序列執行,如果只有一個定時任務,這樣做肯定沒問題,當定時任務增多,如果一個任務卡死,會導致其他任務也無法執行。
3.1 多執行緒配置類 AsyncConfig.class
@Configuration // 表明該類是一個配置類
@EnableAsync // 開啟非同步事件的支援
public class AsyncConfig {
@Value("${myProps.corePoolSize}")
private int corePoolSize;
@Value("${myProps.maxPoolSize}")
private int maxPoolSize;
@Value("${myProps.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;
}
}
3.2 配置檔案application.yml
中新增多執行緒配置
myProps:
corePoolSize: 10
maxPoolSize: 100
queueCapacity: 10
3.3 在定時任務的類或者方法上新增@Async
此時,可讓每一個任務都是在不同的執行緒中,啟動專案,日誌列印如下:
2019-03-11 15:16:54.855 INFO 10782 --- [ main] c.v.t.SpringBootDemoTimeTaskApplication : SpringBootDemoTimeTaskApplication start!
2019-03-11 15:16:55.015 INFO 10782 --- [ taskExecutor-1] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:00.002 INFO 10782 --- [ taskExecutor-2] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:00.002 INFO 10782 --- [ taskExecutor-3] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:05.003 INFO 10782 --- [ taskExecutor-4] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:06.005 INFO 10782 --- [ taskExecutor-5] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:10.004 INFO 10782 --- [ taskExecutor-6] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:12.005 INFO 10782 --- [ taskExecutor-7] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:15.006 INFO 10782 --- [ taskExecutor-8] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:18.004 INFO 10782 --- [ taskExecutor-9] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:20.004 INFO 10782 --- [taskExecutor-10] cn.van.task.service.SchedulerTask : =====>>>>>使用cron執行定時任務-1
日誌列印證明了我的預測,至此,多執行緒中執行定時任務完畢!
四、原始碼及其延伸
https://github.com/vanDusty/SpringBoot-Home/tree/master/springboot-demo-list/task-d