将java.util.Timer再延迟x秒

时间:2018-09-18 10:00:07

标签: java timer thread-sleep

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

答案 0 :(得分:2)

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

尝试睡眠5秒钟。

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

答案 1 :(得分: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。