8000 Create 5分钟搞懂如何在Spring Boot中Schedule Tasks .md · zhangmf-java/springboot-guide@a99d001 · GitHub
[go: up one dir, main page]

Skip to content

Commit a99d001

Browse files
committed
Create 5分钟搞懂如何在Spring Boot中Schedule Tasks .md
1 parent 3de069d commit a99d001

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。
2+
3+
本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。
4+
5+
## Spring Schedule 实现定时任务
6+
7+
我们只需要 SpringBoot 项目最基本的依赖即可,所以这里就不贴配置文件了。
8+
9+
### 1. 创建一个 scheduled task
10+
11+
我们使用 `@Scheduled` 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 `@Scheduled `的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。
12+
13+
> Cron 表达式: 主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作。
14+
>
15+
> 推荐一个在线Cron表达式生成器:[http://cron.qqe2.com/](http://cron.qqe2.com/)
16+
17+
```java
18+
import org.slf4j.Logger;
19+
import org.slf4j.LoggerFactory;
20+
import org.springframework.scheduling.annotation.Scheduled;
21+
import org.springframework.stereotype.Component;
22+
23+
import java.text.SimpleDateFormat;
24+
import java.util.Date;
25+
import java.util.concurrent.TimeUnit;
26+
27+
/**
28+
* @author shuang.kou
29+
*/
30+
@Component
31+
public class ScheduledTasks {
32+
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
33+
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
34+
35+
/**
36+
* fixedRate:固定速率执行。每5秒执行一次。
37+
*/
38+
@Scheduled(fixedRate = 5000)
39+
public void reportCurrentTimeWithFixedRate() {
40+
log.info("Current Thread : {}", Thread.currentThread().getName());
41+
log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date()));
42+
}
43+
44+
/**
45+
* fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。
46+
*/
47+
@Scheduled(fixedDelay = 2000)
48+
public void reportCurrentTimeWithFixedDelay() {
49+
try {
50+
TimeUnit.SECONDS.sleep(3);
51+
log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date()));
52+
} catch (InterruptedException e) {
53+
e.printStackTrace();
54+
}
55+
}
56+
57+
/**
58+
* initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。
59+
*/
60+
@Scheduled(initialDelay = 5000, fixedRate = 5000)
61+
public void reportCurrentTimeWithInitialDelay() {
62+
log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date()));
63+
}
64+
65+
/**
66+
* cron:使用Cron表达式。 每分钟的1,2秒运行
67+
*/
68+
@Scheduled(cron = "1-2 * * * * ? ")
69+
public void reportCurrentTimeWithCronExpression() {
70+
log.info("Cron Expression: The time is now {}", dateFormat.format(new Date()));
71+
}
72+
}
73+
74+
```
75+
76+
###  2. 启动类上加上`@EnableScheduling`注解
77+
78+
在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。
79+
80+
```java
81+
@SpringBootApplication
82+
@EnableScheduling
83+
public class DemoApplication {
84+
85+
public static void main(String[] args) {
86+
SpringApplication.run(DemoApplication.class, args);
87+
}
88+
}
89+
```
90+
91+
### 3. 自定义线程池执行 scheduled task
92+
93+
默认情况下,`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行,你可以通过在加了`@Scheduled`注解的方法里加上下面这段代码来验证。
94+
95+
```java
96+
logger.info("Current Thread : {}", Thread.currentThread().getName());
97+
```
98+
99+
你会发现加上上面这段代码的定时任务,每次运行都会输出:
100+
101+
```
102+
Current Thread : scheduling-1
103+
```
104+
105+
如果我们需要自定义线程池执行话只需要新加一个实现`SchedulingConfigurer`接口的 `configureTasks` 的类即可,这个类需要加上 `@Configuration` 注解。
106+
107+
```java
108+
@Configuration
109+
public class SchedulerConfig implements SchedulingConfigurer {
110+
private final int POOL_SIZE = 10;
111+
112+
@Override
113+
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
114+
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
115+
116+
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
117+
threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
118+
threadPoolTaskScheduler.initialize();
119+
120+
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
121+
}
122+
}
123+
```
124+
125+
通过上面的验证的方式输出当前线程的名字会改变。
126+

0 commit comments

Comments
 (0)
0