如何实现Spring Boot每秒指定毫秒数执行@Scheduled任务
实现固定毫秒点的每秒定时任务(自定义Trigger方案)
完全可以通过自定义Trigger实现需求,Spring的TaskScheduler支持自定义Trigger来精准控制任务触发时机,能满足毫秒级精度且固定在每秒指定毫秒点的要求。
核心思路
要固定在每秒的指定毫秒(比如900ms)执行,核心是精准计算下一次触发时间:
- 取当前时间的秒级起始点(如20:00:00:000),加上指定毫秒数得到当前秒的目标触发时间
- 如果当前时间已经超过本次秒内的目标点,则直接取下一秒的目标点
代码实现
1. 自定义Trigger类
import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import java.util.Date; public class FixedMillisecondTrigger implements Trigger { private final long targetMillisecond; // 每秒内的目标毫秒数,范围0-999 public FixedMillisecondTrigger(long targetMillisecond) { if (targetMillisecond < 0 || targetMillisecond >= 1000) { throw new IllegalArgumentException("目标毫秒数必须在0-999之间"); } this.targetMillisecond = targetMillisecond; } @Override public Date nextExecutionTime(TriggerContext triggerContext) { long now = System.currentTimeMillis(); // 计算当前秒的起始时间戳 long currentSecondStart = now / 1000 * 1000; // 计算当前秒的目标触发时间 long targetTime = currentSecondStart + targetMillisecond; // 若当前时间已过目标点,直接取下一秒的目标时间 if (now >= targetTime) { targetTime += 1000; } return new Date(targetTime); } }
2. 配置并启动定时任务
在Spring Boot中通过配置类注册任务:
import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; @Configuration @EnableScheduling public class ScheduledTaskConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { // 指定每秒900毫秒处触发任务 FixedMillisecondTrigger trigger = new FixedMillisecondTrigger(900); taskRegistrar.addTriggerTask( // 任务执行逻辑 () -> System.out.printf("[%tT.%tL] 定时任务执行%n", System.currentTimeMillis(), System.currentTimeMillis()), trigger ); } }
关键说明
- 时间稳定性:每次触发时间都基于当前系统时间重新计算,完全不受服务启动时间影响,始终固定在每秒的指定毫秒点
- 无漂移风险:即使任务执行耗时,下一次触发依然会定位到下一秒的目标毫秒点,不会出现时间累积漂移
- 参数合法性校验:构造函数确保传入的目标毫秒数在合法范围内,避免无效配置
内容的提问来源于stack exchange,提问作者Jamie Ditchburn
相关产品推荐
相关产品推荐

