使用仅设置第二个的日历对象启动任务

Start task using calendar object where just the second is set

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

提醒一下,scheduleAtFixedRate 的签名是:

ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

initialDelay和period都是TimeUnit单位。

您正在将 initialDelay 设置为指定时区中当前时间的 UNIX 时间戳,只是 其秒字段设置为 0。供参考,在确切的时刻我检查了这个,UNIX 时间戳是 1432907829。

这意味着您刚刚告诉您的计时器在开始前等待超过 10 亿秒,即 4.32 亿秒,然后每 3 秒 运行。

我不知道你为什么要使用 Calendar 对象(实际上,我不知道为什么 任何人 都会使用一个,但那是另一回事了).

尝试只对当前时间使用整数运算来计算到下一分钟的秒数:

scheduler.scheduleAtFixedRate(new Sched().new RC(), 
    60 - System.currentTimeMillis() / 1000 % 60, 3, TimeUnit.SECONDS);

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