使用ScheduledExecutorService在重复的时间重复运行JAVA程序

时间:2016-04-12 05:04:47

标签: java

我希望安排一个java程序在每小时的第15,25和45分钟运行。例如:

17:15,17:25,17:45,18:15等等......

如何使用 ScheduledExecutorService 实现此目的。我可以看到几个示例,它们可以在使用ScheduledExecutorService触发它们的时间之后的某个时间间隔内触发脚本。

任何人都可以建议我使用相关链接和示例来获得一些想法

3 个答案:

答案 0 :(得分:1)

我找不到安排Timer间隔不均匀的方法。但是,安排Timer以固定间隔执行是相对简单的。

对于您的情况,您可以安排三个计时器,一个用于:15,一个用于:25,一个用于:45一小时:

public class TaskTest {
    public static scheduleTask(int interval) {
        GregorianCalendar cal = new GregorianCalendar();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int date = cal.get(Calendar.DATE);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int hourScheduled = hour;

        // if we are past the scheduled time then schedule for the next hour
        if (minute > interval) {
            ++hourScheduled;
        }
        cal.set(year, month, date, hourScheduled, interval);
        long initialDelay = cal.getTimeInMillis() - System.currentTimeMillis();
        if (initialDelay < 0) {
            initialDelay = 0L;
        }
        // schedule each job for once per hour
        int period = 60*60*1000;

        Timer timer = new Timer();
        SomeTask someTask = new SomeTask();
        timer.scheduleAtFixedRate(someTask, initialDelay, period);
    }

    public static void main(String[] args) {
        // schedule for the 15th, 25th and 45th min of time every hour
        scheduleTask(15);
        scheduleTask(25);
        scheduleTask(45);
    }
}

public class SomeTask extends TimerTask {
    @Override
    public void run() {
        // do something
    }
}

答案 1 :(得分:1)

你想在某个时间点触发你的代码,而不是定期,我认为有几种选择:

  1. 如果您的程序在Linux或其他支持crontab的系统下运行,那么crontab是一个不错的选择。

    我们可以创建多个cron作业来实现你的目标:

    使用命令“crontab -e”编辑cron作业:

  2.   

    15 * * * * / java_path / java your_program parameters

         

    25 * * * * / java_path / java your_program parameters

         

    35 * * * * / java_path / java your_program parameters

         

    45 * * * * / java_path / java your_program parameters

    1. 如果你不想使用crontab,而你只想要一个纯粹的java解决方案,那么quartz会帮助你。

      quartz可以让你配置cron触发器,它们与Linux下的crontab非常相似。

      请参阅http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-06.html以获取更多信息。

    2. 最后,你想要一个纯java和轻量级的解决方案,你可以简单地使用Java Timer和TimerTask,例如:

      公共类App {

      public static void main(String[] args) {
          Timer timer = new Timer();
          TimerTask tt = new SchedulerTask();
          DateFormat df = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
          Date triggerTime = null;
          try {
              triggerTime = df.parse("2016-04-12 13:15:00");
          } catch (ParseException e) {
              e.printStackTrace();
          }
          timer.schedule(tt, triggerTime, 3600*1000);
      }
      
      static class SchedulerTask extends TimerTask {
          @Override
          public void run() {
              System.out.println("I am running at " + Calendar.getInstance().getTime());
          }
      }
      

      }

    3. 你可以创建4个任务,比如上面的任务,在13:15,13:25,13:35,13:45触发,每个任务每小时运行一次。

答案 2 :(得分:0)

您可以使用固定的1小时间隔安排相同的runnable&amp;延迟应根据当前时间而变化。

示例当前时间6:10比第一个时间表的延迟时间为5分钟(6:15),第二个时间表为5 + 10 = 15分钟(6:25)。 这样你可以创建多个时间表,每个时间表有一个小时的延迟。

import java.util.GregorianCalendar;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MultipleScheduler {

    public static void main(String[] args) {

     Runnable task = new Runnable() {

            @Override
            public void run() {

                System.out.println(System.currentTimeMillis() + " Task executed");

            }
        };

        ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

        int BaseDelay = getInitialDelay();

        service.scheduleAtFixedRate(task, BaseDelay, 60, TimeUnit.MINUTES);
        service.scheduleAtFixedRate(task, BaseDelay + 10, 60, TimeUnit.MINUTES);
        service.scheduleAtFixedRate(task, BaseDelay + 30, 60, TimeUnit.MINUTES);



    }

    static int getInitialDelay() {
        GregorianCalendar cal = new GregorianCalendar();
        int minute=cal.get(cal.MINUTE);


        int delay=0;
         //some logic to calculate delay    updated delay should be returned

        return delay;
    }
}