You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@Scheduled定时方法运行时如何通知其他RestController

Spring Boot 多定时任务状态感知实现方案

以下是适配不同部署场景的可落地方案:

方案1:单实例部署场景(内存状态共享)

该方案无需引入额外组件,性能最优,适合单体服务部署场景。

步骤1:定义线程安全的状态持有单例Bean

import org.springframework.stereotype.Component;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 定时任务运行状态全局持有类,Spring单例模式保证多Bean共享同一份状态
 */
@Component
public class ScheduledTaskStatus {
    // 原子布尔类保证线程可见性、原子性,避免并发修改异常
    private final AtomicBoolean methodARunningFlag = new AtomicBoolean(false);

    public boolean isMethodARunning() {
        return methodARunningFlag.get();
    }

    public void setMethodARunning(boolean status) {
        methodARunningFlag.set(status);
    }
}

步骤2:修改ControllerA的methodA逻辑,更新运行状态

@Controller
public class ControllerA {
    private final ScheduledTaskStatus scheduledTaskStatus;

    // 构造注入状态持有Bean
    public ControllerA(ScheduledTaskStatus scheduledTaskStatus) {
        this.scheduledTaskStatus = scheduledTaskStatus;
    }

    @Scheduled(cron = "0 0/2 * * * *", zone = "GMT")
    public void methodA() {
        try {
            // 任务启动前更新状态为运行中
            scheduledTaskStatus.setMethodARunning(true);
            // 原有业务逻辑
            // do something
        } finally {
            // 任务结束(无论成功/异常)强制复位状态,避免永久标记为运行中
            scheduledTaskStatus.setMethodARunning(false);
        }
    }
}

步骤3:ControllerB中直接读取状态

@Controller
public class ControllerB {
    private final ScheduledTaskStatus scheduledTaskStatus;

    public ControllerB(ScheduledTaskStatus scheduledTaskStatus) {
        this.scheduledTaskStatus = scheduledTaskStatus;
    }

    @Scheduled
    public void methodB() {
        if (scheduledTaskStatus.isMethodARunning()) {
            // 此时已感知到methodA正在运行,执行对应逻辑
        }
    }
}

方案2:分布式多实例部署场景

如果服务是集群部署,内存状态无法跨实例共享,可使用以下两种实现:

  • Redis共享状态:methodA启动时往Redis写入带过期时间的标识key,任务结束删除key,methodB执行时查询该key是否存在即可判断运行状态,注意过期时间需略大于methodA的最大预计运行时长,避免实例宕机导致脏状态。
  • Spring事件+消息队列:如果需要实时触发通知而非定时轮询状态,可在methodA启动/结束时发布事件,通过MQ广播到所有实例,各实例本地维护状态标识即可。

注意事项

  • 不要使用普通的boolean变量作为状态标识,多线程场景下会有可见性问题,导致状态读取不准
  • 状态复位逻辑必须放在finally代码块中,避免业务代码抛出异常导致状态永远为运行中

内容的提问来源于stack exchange,提问作者ErEcTuS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 15:24:03