【问题标题】:How to run a task DURING PARTICULAR PERIOD OF TIME with ScheduledExecutorService?如何在特定时间段内使用 ScheduledExecutorService 运行任务?
【发布时间】:2019-08-18 20:26:01
【问题描述】:

我正在尝试创建一个计划作业,该作业从每天早上 7 点到下午 22 点每 5 分钟运行一次。例如,它应该在 7:00、7:05、7:10 ... 21:55 运行,然后它应该在 22:00 停止。第二天,它再次运行相同的计划,依此类推。

我找到了这个例子,它展示了如何使用ScheduledExecutorService 在特定时间启动任务。 How to run certain task every day at a particular time using ScheduledExecutorService?

我参考了答案并编写了如下代码: (我使用的是 Java 7)

class Scheduler {
    private ScheduledExecutorService executors;

    public static void main(String[] arg) {
       Runnable task = new Runnable() {
            @Override
            public void run() {
                ...DO SOMETHING...
            }
       };
        
       // Get how many seconds before the next start time (7AM).
       long initDelay = getInitialDelay(7); 
       
       ScheduledExecutorService executors = Executors.newSingleThreadScheduledExecutor();
       executors.scheduleAtFixedRate(task, initDelay, (60 * 5), TimeUnit.SECONDS);
   }

    private static long getInitialDelay(int hour) {
        Calendar calNow = Calendar.getInstance();

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        long diff = cal.getTimeInMillis() - calNow.getTimeInMillis();
        if (diff < 0) {
            cal.add(Calendar.DAY_OF_MONTH, 1);
            diff = cal.getTimeInMillis() - calNow.getTimeInMillis();
        }

        return diff / 1000;
    }
}

我上面的代码从早上 7 点开始,每 5 分钟运行一次。但是,如何控制ScheduledExecuterService在下午 22 点停止任务,然后在第二天早上 7 点重新开始?

或者,有没有更好的方法在每天的特定时间段内运行任务?

【问题讨论】:

  • 顺便说一下,Calendar 是一个糟糕的类,几年前随着 JSR 310 的采用被现代 java.time 类所取代。对于 Java 6 和7、查看ThreeTen-Backport项目。

标签: java scheduled-tasks scheduledexecutorservice


【解决方案1】:

一个固定的调度执行器服务不能改变它的时间。

所以使用单次运行的非固定调度执行器服务。致电ScheduledExecutorService::schedule。在第一次运行时,检查当前时间。如果在工作日结束之前,再次调用相同的方法schedule,延迟五分钟。如果在工作日结束后延迟了八小时,则为新工作日开始之前的时间量。

所以,一个简单的小技巧。您的可运行文件的每次运行都会无休止地安排下一次运行。

【讨论】:

  • 你的意思是我应该创建嵌套的 Executors 吗?
  • @edyucheng 不,只有一个ScheduledExecutorService 对象。只有一个 Runnable 对象。您的Runnable 可以调用schedule 方法来安排自己的下一次运行。我明天也许可以写一个例子,尽管 Stack Overflow 上的一些这样的答案已经表明了这一点。或者你可以考虑一下,因为它真的很简单。检查run 方法中的时间。
  • 调度下一次运行并运行下一次运行后,如何再次调用schedule方法?我尝试使用无限循环并将​​schedule 方法放入其中,但它显示错误。while(true) { executor.schedule(task, 5, TimeUnit.MINUTE); }。你能展示如何控制并举例说明吗?非常感谢!
猜你喜欢
  • 2013-12-21
  • 2020-05-24
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多