无限循环+线程休眠替代cron job

3

今天我有个想法… 我想听听反馈。我有一个需要每5分钟检查一个目录的Java应用程序。简单明了,这个应用程序需要每五分钟运行一次。

看起来很适合使用cronjob,但我在想…为什么不像这样把逻辑/时间都放在应用程序里(显然是简化的):

public static void main(String[] args) {
    while(true) { // repeatedly execute...
        // do the work/job
        Thread.sleep(600 * 1000); // make the thread sleep for 5 minutes
    }
}

我看到的一个显著缺点是“一旦该应用程序启动,我们如何停止它?删除它吗?”

除此之外,还有其他重要的缺点吗?

我应该停止白日梦,只使用cron作业吗?

4个回答

6
一些显著的缺点:
  • 如果您想要更改轮询频率(例如每2分钟或每10分钟一次),则必须更改程序。如果您具有不规律的轮询计划,比如周一至周五每5分钟一次,但周六和周日每15分钟一次,那么这特别困难。当然,您可能认为您的程序永远不需要进行这样的更改,但需求会演变。
  • 正如您所说,杀死进程是停止程序的唯一方法。而在处理过程中终止它可能是个坏事。当然,您可以添加取消逻辑,但这需要额外的开发时间。
  • 该程序在闲置时占用内存(大部分时间)。这是一种资源浪费。当您使用具有许多千兆字节内存的系统时,可能不是很重要,但在具有有限内存的嵌入式系统上,则成为一个问题。
  • 当操作系统中已经有一个完美的调度程序内置时,编写自己的调度程序是浪费时间并需要进行调试和维护。

我将此程序称为“打盹程序(catnap program)”,因为它就像一只猫一样:大部分时间都在睡觉,偶尔醒来伸个懒腰,可能玩弄几分钟的绳子,然后又回去睡觉。 程序不是猫


说实话,如果循环间隔是从命令行(或其他地方)读取的变量而不是一个字面常量,那么循环间隔可以很容易地更改。程序并不是猫,这是公平的,但猫线程不一定是个坏主意 :) - Martin James

3
您可以使用ScheduledExecutorService以固定的速率运行任务,并在某些操作(例如读取System.in)时停止它:
public static void main(String[] args) throws InterruptedException {
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
    ses.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            // do some work
        }
    }, 0, 5, TimeUnit.MINUTES);  // every 5 minutes

    // when anything is entered, the task is stopped
    Scanner sc = new Scanner(System.in);
    String whatever = sc.next();
    // shutdown the executor
    ses.shutdown();
    ses.awaitTermination(15, TimeUnit.SECONDS);
}

那么代码不会在 ses.scheduleAtFixedRate(...) 处阻塞吗? - Don Cheadle

2
一个像建议的这样的解决方案的优点是它可以在没有cron的操作系统上运行(但每个操作系统都会有某种类型的调度程序)。
另一方面,使用cron具有以下优点:
- 即使任务崩溃,也将在下一个预定时间运行;而所示的解决方案在崩溃后不会再次运行,直到有人重新启动它。 - 在重新启动后,cron将重新开始运行任务;而所提出的解决方案则不会这样做。 - 当任务周期性地停止然后关闭时,内存泄漏比长时间运行的进程更不重要。
通过枚举随着时间推移添加到操作系统级作业调度程序中的更多功能,可以无疑地将此列表扩展得更长。

0

我会在我的应用程序中使用Quartz调度程序。链接http://quartz-scheduler.org/

它可以控制应用程序的启动和停止。虽然需要进行更多的设置,但非常灵活。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接