欢迎来到淼淼之森的个人小站。  交流请加我微信好友: studyjava。  也欢迎关注同名公众号:Java学习之道

@Scheduled注解常用方法 置顶!

  |   0 评论   |   0 浏览

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)
cronCron表达式,按复杂时间规则执行@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表达式生成器

Spring官方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 协议

本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。若本站转载文章遗漏了原文链接,请及时告知,我们将做删除处理!文章观点不代表本网站立场,如需处理请联系首页客服。
• 网站转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。
• 公众号转载请联系网站首页的微信号申请白名单!

个人微信公众号 ↓↓↓                 

微信搜一搜 Java 学习之道