@Scheduled注解常用方法 置顶!
0. 序言
在Java中,@Scheduled
是 Spring Framework 提供的注解,用于 定时任务调度。它可以让方法在指定的时间间隔或固定时间点自动执行,常用于后台任务、定时数据处理、心跳检测等场景。
1. @Scheduled
的基本用法
启用定时任务
在Spring Boot项目中,首先需要在配置类或主类上添加 @EnableScheduling
注解,以启用定时任务功能:
@SpringBootApplication
@EnableScheduling // 启用定时任务
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
定义定时任务方法
在需要定时执行的方法上添加 @Scheduled
注解,并指定执行时间规则:
@Component
public class MyScheduledTasks {
// 每5秒执行一次
@Scheduled(fixedRate = 5000)
public void task1() {
System.out.println("Task 1 executed at: " + new Date());
}
// 延迟2秒后首次执行,之后每3秒执行一次
@Scheduled(fixedDelay = 3000, initialDelay = 2000)
public void task2() {
System.out.println("Task 2 executed at: " + new Date());
}
// 使用Cron表达式(每分钟的第30秒执行)
@Scheduled(cron = "30 * * * * ?")
public void task3() {
System.out.println("Task 3 executed at: " + new Date());
}
}
2. @Scheduled
的主要参数
参数 | 说明 | 示例 |
---|---|---|
fixedRate | 固定速率(毫秒),任务开始后每隔指定时间执行一次,不考虑任务本身耗时 | @Scheduled(fixedRate = 5000) |
fixedDelay | 固定延迟(毫秒),任务结束后延迟指定时间再执行下一次 | @Scheduled(fixedDelay = 3000) |
initialDelay | 初始延迟(毫秒),首次执行前的延迟时间 | @Scheduled(initialDelay = 2000, fixedRate = 5000) |
cron | Cron表达式,按复杂时间规则执行 | @Scheduled(cron = "0 0/5 * * * ?") |
3. Cron表达式详解
Cron表达式由6或7个字段组成,格式为:
秒 分 时 日 月 周 [年]
(年可选)
常用Cron示例
表达式 | 说明 |
---|---|
"0 * * * * ?" | 每分钟的0秒执行(每分钟一次) |
"0 0/5 * * * ?" | 每5分钟执行一次 |
"0 0 12 * * ?" | 每天中午12点执行 |
"0 15 10 ? * MON-FRI" | 每周一到周五的10:15执行 |
"0 0 0 L * ?" | 每月最后一天的午夜执行 |
在线工具
• Cron表达式生成器
4. 注意事项
(1)单线程执行问题
默认情况下,所有 @Scheduled
任务由 同一个线程池(单线程) 执行。如果某个任务耗时较长,可能会阻塞其他任务。
解决方案:自定义线程池:
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5)); // 5个线程
}
}
(2)避免长时间运行的任务
如果任务执行时间超过调度间隔(如 fixedRate
),可能会导致任务堆积。建议:
• 使用 fixedDelay
替代 fixedRate
。
• 在方法内部处理超时逻辑。
(3)分布式环境问题
在集群部署时,@Scheduled
会在所有节点上同时执行。若需避免重复执行,需借助分布式锁(如Redis或ZooKeeper)。
5. 高级用法
动态修改Cron表达式
通过 Trigger
接口实现动态调度:
@Component
public class DynamicScheduler {
private final ScheduledTaskRegistrar registrar;
public DynamicScheduler(ScheduledTaskRegistrar registrar) {
this.registrar = registrar;
}
public void scheduleTask(String newCron) {
registrar.addTriggerTask(
() -> System.out.println("Dynamic task executed at: " + new Date()),
triggerContext -> new CronTrigger(newCron).nextExecutionTime(triggerContext)
);
}
}
条件化启用任务
结合 @Conditional
或配置文件控制任务是否启用:
@Scheduled(fixedRate = 5000)
@ConditionalOnProperty(name = "scheduler.enabled", havingValue = "true")
public void conditionalTask() {
// 仅当配置为true时执行
}
总结
• @Scheduled
+ @EnableScheduling
是Spring中最简单的定时任务方案。
• fixedRate
/fixedDelay
适合简单间隔任务,Cron 适合复杂时间规则。
• 注意单线程阻塞问题,必要时自定义线程池。
• 分布式环境需额外处理(如分布式锁)。
如果需要更强大的调度功能(如任务持久化、失败重试),可以考虑 Quartz 框架。
标题:@Scheduled注解常用方法
作者:mmzsblog
地址:https://www.mmzsblog.cn/articles/2025/05/07/1746623710737.html
如未加特殊说明,文章均为原创,转载必须注明出处。均采用CC BY-SA 4.0 协议!
本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。若本站转载文章遗漏了原文链接,请及时告知,我们将做删除处理!文章观点不代表本网站立场,如需处理请联系首页客服。• 网站转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。
• 公众号转载请联系网站首页的微信号申请白名单!
