导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
常用注解
@Scheduled
定时任务的核心
cron
: cron表达式,根据表达式循环执行,与fixedRate属性不同的是它是将时间进行了切割。(@Scheduled(cron = "0/5 * * * * *"
)任务将在5、10、15、20...
这种情况下进行工作)fixedRate
: 每隔多久执行一次;(@Scheduled(fixedRate = 1000)
假设第一次工作时间为2018-05-29 16:58:28,工作时长为3秒,那么下次任务的时候就是2018-05-29 16:58:31,配置成异步后,只要到了执行时间就会开辟新的线程工作),如果(@Scheduled(fixedRate = 3000
) 假设第一次工作时间为2018-05-29 16:58:28,工作时长为1秒,那么下次任务的时间依然是2018-05-29 16:58:31
)fixedDelay
: 当前任务执行完毕后等待多久继续下次任务(@Scheduled(fixedDelay = 3000
) 假设第一次任务工作时间为2018-05-29 16:54:33,工作时长为5秒,那么下次任务的时间就是2018-05-29 16:54:41)initialDelay
: 第一次执行延迟时间,只是做延迟的设定,与fixedDelay
关系密切,配合使用,相辅相成。
Cron说明:
这是一个时间表达式,可以通过简单的配置就能完成各种时间的配置,我们通过CRON表达式几乎可以完成任意的时间搭配,它包含了六或七个域:
Seconds : 可出现", - * /"四个字符,有效范围为0-59的整数
Minutes : 可出现", - * /"四个字符,有效范围为0-59的整数
Hours : 可出现", - * /"四个字符,有效范围为0-23的整数
DayofMonth : 可出现", - * / ? L W C"八个字符,有效范围为0-31的整数
Month : 可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEc
DayofWeek : 可出现", - * / ? L C #"四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推
Year : 可出现", - * /"四个字符,有效范围为1970-2099年
下面简单举几个例子:
"0 0 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分每分钟一次触发
"0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发
"0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
"0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发
"0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发
"0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发
@Async
代表该任务可以进行异步工作,由原本的串行改为并行
@EnableScheduling
表示开启对@Scheduled
注解的解析;同时new ThreadPoolTaskScheduler()
也是相当的关键,通过阅读过源码可以发现默认情况下的private volatile int poolSize = 1;
这就导致了多个任务的情况下容易出现竞争情况(多个任务的情况下,如果第一个任务没执行完毕,后续的任务将会进入等待状态)。
@EnableAsync
表示开启@Async
注解的解析;作用就是将串行化的任务给并行化了。(@Scheduled(cron = "0/1 * * * * *")
假设第一次工作时间为2018-05-29 17:30:55
,工作周期为3秒;如果不加@Async
那么下一次工作时间就是2018-05-29 17:30:59
;如果加了@Async
下一次工作时间就是2018-05-29 17:30:56
)
示例
@Component
public class SpringTaskDemo {
private static final Logger log = LoggerFactory.getLogger(SpringTaskDemo.class);
@Async
@Scheduled(cron = "0/1 * * * * *")
public void scheduled1() throws InterruptedException {
Thread.sleep(3000);
log.info("scheduled1 每1秒执行一次:{}", LocalDateTime.now());
}
@Scheduled(fixedRate = 1000)
public void scheduled2() throws InterruptedException {
Thread.sleep(3000);
log.info("scheduled2 每1秒执行一次:{}", LocalDateTime.now());
}
@Scheduled(fixedDelay = 3000)
public void scheduled3() throws InterruptedException {
Thread.sleep(5000);
log.info("scheduled3 上次执行完毕后隔3秒继续执行:{}", LocalDateTime.now());
}
}
/**
*
* No task executor bean found for async processing: no bean of type TaskExecutor and no bean named 'taskExecutor' either
* 很关键:默认情况下 TaskScheduler 的 poolSize = 1
*
* @return 线程池
*/
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
return taskScheduler;
}