将java.util.Timer延迟x秒

问题描述 投票:1回答:2

我试图每三秒钟运行一次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

我错过了什么?

java timer thread-sleep
2个回答
2
投票

你的2秒睡眠只能在TimerTask触发器之间的3秒间隔内模拟2秒的工作。因此,在睡眠后大约1秒钟,您的计时器将再次启动。

尝试睡5秒钟。

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


1
投票

您当前的代码只是将日期的打印延迟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上的文档

对应于每个Timer对象的是一个后台线程,用于按顺序执行所有计时器的任务。计时器任务应该快速完成。如果计时器任务花费过多时间来完成,它会“占用”计时器的任务执行线程。反过来,这可以延迟后续任务的执行,后续任务可以在紧急任务最终完成时(以及如果)快速连续地“聚集”并执行。

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

© www.soinside.com 2019 - 2024. All rights reserved.