再延迟 java.util.Timer x 秒

Delay java.util.Timer by another x seconds

我正在尝试每三秒运行一个java.util.Timer,我需要在特定条件下再延迟2。为了检查这是否可以使用 Thread.sleep() 实现,我在下面编写了代码。

Timer t = new Timer();

t.schedule(new TimerTask() {
    @Override
    public void run() {
        if (true) { //When this is false timer should continue at 3 second interval.
            try {
                Thread.currentThread().sleep(2000); //Delay by another 2 seconds.
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        System.out.println(new Date());
    }
}, 0, 3000); //Trigger every 3 seconds.

我希望打印出相差 5 秒的时间戳。但我得到的是 3 秒的差异。

Tue Sep 18 15:08:17 IST 2018
Tue Sep 18 15:08:20 IST 2018
Tue Sep 18 15:08:23 IST 2018
Tue Sep 18 15:08:26 IST 2018
Tue Sep 18 15:08:29 IST 2018

我错过了什么?

您的 2 秒睡眠只是在 TimerTask 触发器之间的 3 秒间隔内模拟 2 秒的工作。所以在你睡觉后大约 1 秒,你的计时器会再次启动。

试试睡 5 秒。

但是,请记住,以这种方式延迟不是很稳定。计时器将考虑所有落后于计划的任务,并在前一个任务完成后立即按顺序触发它们。如果您真的想这样做,最好取消任务并将它们重新安排为 5 秒间隔。

您当前的代码只是将日期的打印延迟了 2 秒。它仍然会以 3 秒为间隔。

例如:开始日期 x:

如果没有 Thread.sleep,您将打印在:

x, x + 3, x + 6, x + 9

使用 Thread.sleep,您将打印在:

x + 2, x + 3 + 2, x + 6 + 2, x + 9 + 2

等于:

x + 2, x + 5, x + 8, x + 11 etc

所以每次打印之间还有3秒的延迟。

请参阅 https://docs.oracle.com/javase/8/docs/api/java/util/Timer.html

处的文档

Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially. Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.

同一线程将用于处理您的计时器任务的每次执行。当任务为 运行 并且在计时器触发下一次执行任务之前没有及时完成时,下一次执行将延迟到上一次执行完成。该行为类似于线程池大小为 1 的 ScheduledThreadPoolExecutor。