个人博客


在一些业务场景中,需要自动的去执行一些功能代码,比如定时发送心跳等操作。

1、启用定时任务

在启动类上添加注解@EnableScheduling

1
2
3
4
5
6
7
@SpringBootApplication
@EnableScheduling
public class TaskApplication {
public static void main(String[] args) {
SpringApplication.run(TaskApplication.class, args);
}
}

2、创建定时任务配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Component
@Slf4j
public class ScheduleTask {
/**
* cron表达式
* 每3秒执行一次
*/
@Scheduled(cron = "*/3 * * * * ?")
public void run1() {
log.info("======cron======");
}

/**
* 启动后10秒开始执行,固定5秒周期执行一次
*/
@Scheduled(initialDelay = 10000, fixedRate = 5000)
public void run2() {
log.info("======fixedRate======");
}

/**
* 启动后10秒开始执行,距离上次执行结束之后20秒再开始执行下一次
*/
@Scheduled(initialDelay = 10000, fixedDelay = 20000)
public void run3() {
log.info("======fixedDelay======");
}
}

主要有3种方式设置执行周期:

  1. cron表达式:最灵活的方式,可以根据表达式设定执行时间。
  2. fixedRate:固定周期执行,执行周期 = max(fixedRate, 业务代码执行耗时)。
  3. fixedDelay:上一次执行结束之后开始计时,执行周期 = fixedDelay + 业务代码执行耗时。

3、异步执行定时任务

如果在定时任务多,业务执行时间比较长的情况下,如果使用同步处理,就会发生定时任务不能及时执行的情况。就需要用到异步机制来执行定时任务。

3.1、配置异步任务的线程池

1
2
3
4
5
6
7
8
9
10
11
12
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("scheduleTask-");
executor.setAwaitTerminationSeconds(60 * 5);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}

3.2、启动类添加@EnableAsync注解

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class TaskApplication {
public static void main(String[] args) {
SpringApplication.run(TaskApplication.class, args);
}
}

最后在需要异步执行的定时任务方法或类上添加@Async注解即可生效。

参考链接

代码地址