我希望安排一个java程序在每小时的第15,25和45分钟运行。例如:
17:15,17:25,17:45,18:15等等......
如何使用 ScheduledExecutorService 实现此目的。我可以看到几个示例,它们可以在使用ScheduledExecutorService触发它们的时间之后的某个时间间隔内触发脚本。
任何人都可以建议我使用相关链接和示例来获得一些想法
答案 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)
你想在某个时间点触发你的代码,而不是定期,我认为有几种选择:
如果您的程序在Linux或其他支持crontab的系统下运行,那么crontab是一个不错的选择。
我们可以创建多个cron作业来实现你的目标:
使用命令“crontab -e”编辑cron作业:
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
如果你不想使用crontab,而你只想要一个纯粹的java解决方案,那么quartz会帮助你。
quartz可以让你配置cron触发器,它们与Linux下的crontab非常相似。
请参阅http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-06.html以获取更多信息。
最后,你想要一个纯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());
}
}
}
你可以创建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;
}
}