代码之家  ›  专栏  ›  技术社区  ›  whistling_marmot

当计算机在睡眠后醒来时,计划任务会运行数千次

  •  0
  • whistling_marmot  · 技术社区  · 5 年前

    用Spring的注释方法 @Scheduled 并指定固定延迟,如下所示:

    @Scheduled(fixedRate = 5000)
    public void test() {
        log.info("The time is {}", Instant.now());
    }
    

    当我在睡觉后唤醒电脑时,任务会一个接一个地运行多次。

    The time is 2020-07-14T08:00:30.358073400Z
    The time is 2020-07-14T08:00:35.358969600Z
    The time is 2020-07-14T08:00:40.358066100Z
    ...
    The time is 2020-07-14T08:02:51.806689500Z
    The time is 2020-07-14T08:02:51.806689500Z
    The time is 2020-07-14T08:02:51.806689500Z
    The time is 2020-07-14T08:02:51.806689500Z
    The time is 2020-07-14T08:02:51.806689500Z
    The time is 2020-07-14T08:02:51.807651500Z
    The time is 2020-07-14T08:02:51.807651500Z
    ...
    

    如何使它在计算机唤醒时只运行一次?

    0 回复  |  直到 5 年前
        1
  •  1
  •   user10871691 user10871691    5 年前

    用途: @Scheduled(cron = "*/5 * * * * *") .

    使用cron表达式时,错过的执行不会排队。

    此外,正如@Lino所注意到的,你指定了一个 fixedRate 而不是a fixedDelay .更改 固定日期 固定延迟 也解决了你的问题,但要考虑到自那以后行为可能会发生变化 固定延迟 是以毫秒为单位的固定周期 在上一次调用结束和下一次调用开始之间 虽然 固定日期 是以毫秒为单位的固定周期 调用之间 .

        2
  •  0
  •   Lino    5 年前

    你可以利用 AtomicBoolean 标志,表示任务已在运行:

    private final AtomicBoolean running = new AtomicBoolean(false);
    

    然后按照你预定的方法

    if (running.compareAndSet(false, true)) {
        log.info("The time is {}", Instant.now());
        running.set(false);
    }
    

    从javadoc compareAndSet(expect, update) :

    如果当前值==预期值,则原子地将值设置为给定的更新值。

    退换商品 : true 如果成功。 False return表示实际值不等于预期值。

    所以 if 将检查当前是否没有任务正在运行,然后才执行您的代码。