【问题标题】:Scheduled task using ScheduledExecutorService ? A good idea?使用 ScheduledExecutorService 的计划任务?一个好主意?
【发布时间】:2016-10-25 11:38:49
【问题描述】:

我需要每天执行一些任务。我可以为此使用 ScheduledExecutorService 吗?说一段总是以特定间隔运行的代码。我怀疑我总是让 CPU 忙于运行我的代码,但这段代码将在一天、一周或一个月内运行一次我的实际任务,具体取决于配置。

ScheduledExecutorService schedular = Executors.newScheduledThreadPool(1);
schedular.scheduleAtFixedRate(new MySchedular(), 1, 24, TimeUnit.HOUR);

或者我们有更好的选择吗?

【问题讨论】:

  • 担心的不是 CPU 会很忙,因为当代码只是在等待(长达一个月的)计时器时,进程应该休眠。更大的问题来自进程结束(例如,机器重新启动)并且没有任何东西可以重新启动它。不同的系统对这种间隔任务有不同的机制,*nixs有cron,但我不知道你的系统。
  • 您使用哪个版本的 Java?
  • 您使用哪个操作系统?
  • 如果您使用 Linux,那么 CronJob 将是最好的选择,一切都由 cron 作业完成,您只需要提供要执行的脚本路径...。
  • @msw - 我使用的是 Windows 7,在 Windows 中,所有 .bat 文件都会在机器启动/登录时执行(如果你将它放在 C:\Users\\AppData\Roaming\ Microsoft\Windows\Start Menu\Programs\Startup).. Windows 触发我的 .bat 文件,该文件触发我的 java 代码。无需手动触发。

标签: java multithreading concurrency


【解决方案1】:

对于非常基本的需求,您确实可以使用ScheduledExecutorService,但如果您想做复杂的事情,例如在一天中的特定时间安排您的任务,您应该考虑使用quartz-scheduler

这是在晚上 10 点安排任务的方法:

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

JobDetail job = JobBuilder.newJob(MySchedular.class)
    .withIdentity("job1", "group1")
    .build();

Trigger trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger1", "group1")
    .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(22, 00))
    .build();

// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger);
// and start it off
scheduler.start();

使用cron expression 创建的相同触发器将是:

Trigger trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(CronScheduleBuilder.cronSchedule("0 22 00 * * ?"))
    .build(); 

【讨论】:

  • 我从 ScheduledExecutorService 中了解到,JVM 在内存中的某处注册它的下一个执行时间并维护它,每当那个时刻到来时,它(JVM)执行它的任务并在内存中并行更新下一个执行时间。并且循环继续,直到我们的程序终止。所以看起来 CPU 正忙于我们的程序,但实际上并非如此。
  • 确实ScheduledExecutorService不会消耗太多CPU,只有你的任务会
  • 但是正如我的回答中提到的,如果您希望能够在固定时间安排任务,则需要自己实现逻辑,ScheduledExecutorService 无法单独完成。
【解决方案2】:

考虑到您使用的是 Windows 并且 CronJob 不可用,ScheduledExecutorService 对您来说是一个非常好的选择。您需要研究的唯一问题是,如果您的进程因任何原因而终止,而不是由于 Windows 重新启动,会发生什么情况。通常,关键系统有某种看门狗进程来监视您的进程并在它被终止时重新启动它。但这可能超出了这个问题的范围。简而言之,您的问题的答案是:ScheduledExecutorService 是正确的选择。

【讨论】:

    猜你喜欢
    • 2011-04-22
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多