【问题标题】:What is the best way to minimize drift while scheduling a task in java? [duplicate]在 java 中调度任务时,最小化漂移的最佳方法是什么? [复制]
【发布时间】:2020-09-21 10:23:34
【问题描述】:

我正在尝试安排一项任务,但错过请求时间的错误窗口为 1-2 秒。由于漂移,我想递归检查时间并进行调整。我在很短的时间内(最大延迟:15 分钟)运行了这段代码,它运行得很好。但在大多数情况下,这项工作将安排在从现在开始的 8 到 12 小时内。

    public void scheduleTask(LocalDateTime localDateTime)  {

        long delay = ChronoUnit.MILLIS.between(LocalDateTime.now(),localDateTime);
        if (delay < 30000) {
            ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            scheduler.schedule(() -> myTask() ,delay, TimeUnit.MILLISECONDS);
        }
        else {
            try {
                Thread.sleep(delay/2);
            } catch (InterruptedException ignored) {
            }

            scheduleTask(localDateTime);
        }
    }

我在这里查看了各种主题,但找不到真正的解决方案。大多数人都说不可能在准确的时间运行代码,因为调度程序是基于延迟而不是给定时间运行的。

考虑到 8-12 小时的周期,递归调用函数是否会在任何方面影响计算机?如果是,我应该如何克服?

【问题讨论】:

  • 您到底想达到什么目的?为什么不直接安排任务呢?当您将任务安排到未来 12 小时后,您很可能不会遇到问题
  • 欢迎堆栈溢出。请阅读此处stackoverflow.com/help/how-to-ask 的问题指南,并请注意,同时提出多个问题是一种将问题标记为删除的选项。
  • @Lino 计算机将被大量使用(很可能)用于其他目的,我不知道它如何影响计划任务的计时器。我不知道它有多有感觉。

标签: java scheduled-tasks


【解决方案1】:

尝试将 int 值写入文件,并使用您希望程序启动事件的 UNIX 纪元的 int。 经常调用一个函数,根据 UNIX 纪元的当前 int 检查该值。 如果您需要精确,请在异步任务中执行。 如果您不需要精确的时间并且不需要它在应用程序外部触发,请在创建和恢复等其他事件中执行。

如果您需要精度,那么: 主要问题是保持应用程序处于活动状态。粘性异步任务可以做到这一点。即使使用粘性异步任务,您也可以使用 Thread.sleep(30000); 使其空闲(消耗很少的资源);从而减少检查文件的频率。

如果存在互联网,您还可以考虑 firebase 或一些自定义消息传递系统,其中服务器将通过 cron 作业传递消息。稳定服务器上的 Cron 作业是一种非常可靠的方式,可以在未来触发某些事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 2012-06-12
    • 2021-03-16
    • 2011-01-02
    • 1970-01-01
    • 2010-10-13
    相关资源
    最近更新 更多