创建定时任务
在SpringBoot中创建定时任务,实现每过5秒输出一下当前时间。
- 在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 创建定时任务实现类
@Component
public class ScheduledTasks {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("现在时间:" + dateFormat.format(new Date()));
}
}
- 运行程序,控制台中可以看到类似如下输出,定时任务开始正常运作了。
2021-07-13 14:56:56.413 INFO 34836 — [ main] c.d.chapter71.Chapter71Application : Started Chapter71Application in 1.457 seconds (JVM running for 1.835)
2021-07-13 14:57:01.411 INFO 34836 — [ scheduling-1] com.didispace.chapter71.ScheduledTasks : 现在时间:14:57:01
2021-07-13 14:57:06.412 INFO 34836 — [ scheduling-1] com.didispace.chapter71.ScheduledTasks : 现在时间:14:57:06
2021-07-13 14:57:11.413 INFO 34836 — [ scheduling-1] com.didispace.chapter71.ScheduledTasks : 现在时间:14:57:11
2021-07-13 14:57:16.413 INFO 34836 — [ scheduling-1] com.didispace.chapter71.ScheduledTasks : 现在时间:14:57:16
@Scheduled详解
@Scheduled的源码
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED;
//corn:通过cron表达式来配置执行规则
String cron() default "";
//zone:cron表达式解析时使用的时区
String zone() default "";
//fixedDelay:上一次执行结束到下一次执行开始的间隔时间(单位:ms)
long fixedDelay() default -1;
//fixedDelayString:上一次任务执行结束到下一次执行开始的间隔时间,使用java.time.Duration#parse解析
String fixedDelayString() default "";
//fixedRate:以固定间隔执行任务, 即上一次任务执行开始到下一次执行开始的间隔时间(单位:ms),
//若在调度任务执行时,上一次任务还未执行完毕,会加入worker队列,等待上一次执行完成后立即执行下一次任务
long fixedRate() default -1;
//fixedRateString:与fixedRate逻辑一致,只是使用java.time.Duration#parse解析
String fixedRateString() default "";
//initialDelay:首次任务执行的延迟时间
long initialDelay() default -1;
//initialDelayString:首次任务执行的延迟时间,使用java.time.Duration#parse解析
String initialDelayString() default "";
}
1.corn : 该参数接收一个cron表达式,cron表达式是一个字符串,字符串以5或6个空格隔开,分开共6或7个域,每一个域代表一个含义。
cron表达式语法 : [秒] [分] [小时] [日] [月] [周] [年] (年不是必须的)
配置文件:
time:
cron: */5 * * * * *
interval: 5
每5秒执行一次:
@Scheduled(cron="${time.cron}")
void testPlaceholder1() {
System.out.println("Execute at " + System.currentTimeMillis());
}
@Scheduled(cron="*/${time.interval} * * * * *")
void testPlaceholder2() {
System.out.println("Execute at " + System.currentTimeMillis());
}
2. zone#
时区,接收一个java.util.TimeZone#ID。cron表达式会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区。比如我们一般使用的时区Asia/Shanghai。该字段我们一般留空。
3. fixedDelay#
上一次执行完毕时间点之后多长时间再执行。如:
Copy
@Scheduled(fixedDelay = 5000) //上一次执行完毕时间点之后5秒再执行
4. fixedDelayString#
与 3. fixedDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。如:
Copy
@Scheduled(fixedDelayString = “5000”) //上一次执行完毕时间点之后5秒再执行
占位符的使用(配置文件中有配置:time.fixedDelay=5000):
Copy
@Scheduled(fixedDelayString = “${time.fixedDelay}”)
void testFixedDelayString() {
System.out.println("Execute at " + System.currentTimeMillis());
}
5. fixedRate#
上一次开始执行时间点之后多长时间再执行。如:
Copy
@Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行
6. fixedRateString#
与 5. fixedRate 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。
7. initialDelay#
第一次延迟多长时间后再执行。如:
Copy
@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
8. initialDelayString#
与 7. initialDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。
但是这中模式实现的定时任务缺少在集群环境写的协调机制。
假设:
我们要实现一个定时任务,用来每天网上通缉某个数据然后累加到原始数据上。
我们开发测试的时候不会有问题,因为都是单进程在运行的。
但是,当我们把这样的定时任务部署到生产环境时,为了更高的可用性,启动多个实例是必须的。
此时,时间一到,所有启动的实例就会同时开始执行这个任务。
那么问题也就出现了,因为有累加操作,最终我们的结果就会出现问题。
解决这样问题的方式很多种,比较通用的就是采用分布式锁的方式,让同类任务之前的时候以分布式锁的方式来控制执行顺序,比如:使用Redis、Zookeeper等具备分布式锁功能的中间件配合就能很好的帮助我们来协调这类任务在集群模式下的执行规则。
关于SpringBoot定时器的这篇记完啦!!
转自:
https://www.cnblogs.com/mengw/p/11564357.html
https://segmentfault.com/a/1190000040350240