使用下面的代码,我试图在时间的第二部分达到0时启动一个线程 - 即下一分钟开始时。
public class Sched {
public static void main(String args[]) {
Calendar calStart = Calendar.getInstance(TimeZone.getTimeZone("GMT+1"));
calStart.set(Calendar.SECOND, 0);
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new Sched().new RC(), calStart.getTime().getTime(), 3, TimeUnit.SECONDS);
}
private class RC implements Runnable {
public void run() { /* some impl */}
}
}
但线程没有启动。看来我没有正确设置开始时间。我可以通过将initialDelay
参数设置为0
来运行此操作,但为什么使用日历对象设置不起作用?
仅供参考,将initialDelay
硬编码为零(在JDK8上测试):
scheduler.scheduleAtFixedRate(new Sched().new RC(), 0, 3, TimeUnit.SECONDS);
答案 0 :(得分:1)
提醒一下,scheduleAtFixedRate的签名是:
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
initialDelay和period都是TimeUnit单位。
您将initialDelay设置为指定时区的当前时间的UNIX时间戳,其中只其秒字段设置为0.作为参考,在我检查这一点的确切时刻,UNIX时间戳是1432907829。
意思是你刚刚告诉你的计时器等待超过10亿,在它开始之前的4.32亿秒,然后每3秒运行一次。
答案 1 :(得分:0)
我不知道你为什么使用Calendar
对象(实际上,我不知道为什么任何人会使用一个,但这是另一个故事)。
尝试在当前时间使用整数运算来计算到下一分钟的秒数:
scheduler.scheduleAtFixedRate(new Sched().new RC(),
60 - System.currentTimeMillis() / 1000 % 60, 3, TimeUnit.SECONDS);
时区与此代码无关,因为无论您在哪个时区,日期的秒部分都是相同的。