【问题标题】:Delay java.util.Timer by another x seconds将 java.util.Timer 再延迟 x 秒
【发布时间】:2018-09-18 10:00:07
【问题描述】:

我正在尝试每三秒运行一次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


    【解决方案1】:

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

    尝试改为睡眠 5 秒。

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

    【讨论】:

      【解决方案2】:

      您当前的代码只是将日期的打印延迟了 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 对象对应的是一个后台线程 用于按顺序执行计时器的所有任务。定时器任务 应该很快完成。如果一个定时器任务花费了过多的时间 完成后,它会“占用”计时器的任务执行线程。这可以,在 反过来,延迟后续任务的执行,可能会“串起来” 并在(如果)有问题的任务时快速连续执行 终于完成了。

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

      【讨论】:

      • 不,定时器只使用一个线程。如果第一个任务花费的时间超过 3 秒(例如 5 秒),则第二个任务在第一个任务完成之前不会启动。
      • 定时器只使用一个线程。使用Thread.currentThread().hashCode() 验证它。
      • 啊,好吧,你是对的。来自文档:与每个 Timer 对象对应的是一个单独的后台线程,用于按顺序执行所有计时器的任务。定时器任务应该很快完成。如果一个定时器任务花费了过多的时间来完成,它就会“占用”定时器的任务执行线程。反过来,这会延迟后续任务的执行,当(如果)有问题的任务最终完成时,这些任务可能会“聚集”并快速连续执行。我将编辑我的答案以反映这部分。
      • 是的。所以你指出的输出也是预期的(我故意重新排序):x + 2,x + 3 + 2,x + 6 + 2,x + 9 + 2....如果睡眠改为5,那么它变成:x + 5, x + 10, x + 15, x + 20 ...(定时器任务的延迟在第一个任务之后被忽略,因为它们都落后并且“聚集”
      猜你喜欢
      • 2020-11-13
      • 1970-01-01
      • 2017-09-03
      • 2021-06-25
      • 2022-01-27
      • 2020-12-12
      • 1970-01-01
      • 2014-07-25
      • 1970-01-01
      相关资源
      最近更新 更多