Java 如何计算ScheduledExecutorService#scheduleAtFixedRate的初始延迟
我想在一个特定的时间运行一个任务,比如每天晚上7点11分。 我尝试了下面的代码,但它不起作用Java 如何计算ScheduledExecutorService#scheduleAtFixedRate的初始延迟,java,scheduled-tasks,java-7,Java,Scheduled Tasks,Java 7,我想在一个特定的时间运行一个任务,比如每天晚上7点11分。 我尝试了下面的代码,但它不起作用 import java.util.Calendar; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Task3 {
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Task3 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
public void run() {
System.out.println(new Date());
System.out.println("Hello !!");
}
};
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR, 18);
calendar.set(Calendar.MINUTE, 11);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, calendar.getTimeInMillis(), 5, TimeUnit.SECONDS);
}
}
在上面的代码中,我尝试从每天晚上7:11以5秒的间隔运行调度任务。但它的行为并不像我预期的那样。另外,如果我想在另一个条件下做同样的事情,任务应该只在特定的日子执行,比如说每周二和周三
我在计算方法的initialDelay参数时是否犯了某种错误?旁注:使用特殊库(如quartz)可能更简单
initialDelay
参数给出运行任务之前要等待的时间单位数。在您的情况下,您需要计算到7:11的剩余时间
所以它可能看起来像:
long nextRun = calendar.getTimeInMillis();
long initialDelayMillis = nextRun - now;
long oneDayMillis = 1000L * 60 * 60 * 24;
service.scheduleAtFixedRate(runnable, initialDelayMillis, oneDayMillis, TimeUnit.MILLISECONDS);
但这只会处理基本情况。特别是它根本不会处理时钟调整或DST。说“只在星期二和星期五”并不容易
另一种方法是只安排下一次运行,并在runnable结束时重新安排。这样,您就可以更好地控制执行。但底线是:请看我最初的评论。最好是ScheduledExecutor服务。 但也许也可以使用定时器。用于摆动另一个计时器 这里是一个示例(计时器和timerTask可以使用cancel/purge停止)
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimeScheduleTest {
Timer timer = new Timer();
public static void main(String[] args) {
new TimeScheduleTest().startApp();
}
private void startApp() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK,Calendar.TUESDAY);
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 11);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
timer.scheduleAtFixedRate(new StartTimer(), calendar.getTime(), 5000);
}
class StartTimer extends TimerTask {
public void run() {
System.out.println(new Date());
System.out.println("Hello !!");
}
}
}