使用日历对象启动任务,其中只设置第二个

时间:2015-05-29 13:48:17

标签: java multithreading timer

使用下面的代码,我试图在时间的第二部分达到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);

2 个答案:

答案 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);

时区与此代码无关,因为无论您在哪个时区,日期的秒部分都是相同的。