【问题标题】:Supressing redundant jobs in ScheduledThreadPoolExecutor抑制 ScheduledThreadPoolExecutor 中的冗余作业
【发布时间】:2012-08-05 13:58:02
【问题描述】:

我正在使用 ScheduledThreadPoolExecutor 来执行周期性任务。 执行必须是周期性的,不是有固定延迟的。

我遇到了以下问题:考虑一个任务的时间为 1 分钟。如果任务需要 5 分钟才能执行(例如,由于临时网络问题),错过的 执行将排队并在任务完成后立即分派。有没有办法摆脱错过的累积处决?

我尝试使用 remove 方法,但它完全删除了任务,而不仅仅是特定的执行。

谢谢

【问题讨论】:

    标签: java scheduled-tasks scheduling


    【解决方案1】:

    CronScheduler 中,有SkippingToLatest 方法(请参阅Javadocs,“跳到最新运行”部分,专门为您处理此问题:

    Duration syncPeriod = Duration.ofMinutes(1);
    CronScheduler cron = CronScheduler.create(syncPeriod);
    cron.scheduleAtFixedRateSkippingToLatest(0, 1, TimeUnit.MINUTES, runTimeMillis -> {
        // Do your task
    });
    

    【讨论】:

      【解决方案2】:

      可能有更好的方法,但您可以自行重新安排任务。这样,一次执行将始终在前一次执行完成后 1 分钟运行:

      final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
      Runnable yourTask = new Runnable() {
      
          @Override
          public void run() {
              //do your stuff
              scheduler.schedule(this, 1, TimeUnit.MINUTES);
          }
      };
      scheduler.schedule(yourTask, 1, TimeUnit.MINUTES);
      

      编辑

      如果您希望您的任务准确地在 hh:mm:00(精确分钟)运行,您可以将代码替换为

      long millisToNextMinute = 60000 - System.currentTimeMillis() % 60000;
      scheduler.schedule(this, millisToNextMinute, TimeUnit.MILLISECONDS);
      

      【讨论】:

      • 我是这么想的,但是周期会漂移,你可以调整下一次运行的时间。
      • @PeterLawrey 他要求不要运行一些周期性任务,所以无论如何都会有时间漂移。除非他的意思是如果 13:01:00 的任务运行到 13:04:50,那么下一个任务应该在 13:05:00 运行。
      • 如果他这样做,那真的很重要。
      • @assylias- 你说得对。我确实希望任务在其周期的精确倍数上执行。我想知道是否可以不用自己安排时间。
      • @assylias 不应该是:周期 - 经过的百分比周期?
      【解决方案3】:

      您可以将此逻辑构建到任务中。记录上次运行的任务。每次启动时,它应该检查自上次运行以来是否经过了足够的时间。如果没有,那么它应该退出而不做任何工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-17
        • 2019-10-29
        • 2012-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多