如果代码无法按时完成会发生什么

时间:2010-04-06 16:59:11

标签: java timer

如果我设置定时器每3秒执行一次代码。如果代码没有在3秒内完成,会发生什么?计算机将终止代码或等待代码完成或继续计时器,并同时执行带有未完成代码的代码。

如果计算机将同时执行带有未完成代码的代码,那么如果变量涉及该方法会发生什么。例如,第一行可以执行i--,但最后一行是在执行i ++。如果它同时运行,当未完成的代码仍在运行,但是新的运行周期开始时,i值将被新的运行周期添加,所以当前一个周期运行到最后一行时,i值是否会出错(因为新的运行周期正在进行i--,在前一个代码完成之前)。如果是,如何避免呢?

int delay = 0;   // delay for 0 sec.
int period = 3000;  // repeat 3 sec.
int i = 0;
Timer timer = new Timer();

timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            i--;
            // Task here ...
            // It may take more than 3 sec to finish, what will happen?
            i++;
        }
    }, delay, period);

3 个答案:

答案 0 :(得分:5)

每个Timer仅使用一个线程来为其任务提供服务。计时器线程将运行您的任务,直到它完成,然后才尝试安排下一次执行。 Timer Timer承认此问题,并警告用户不要“聚集”任务。

一旦您的任务完成,管理Timer$TimerThread#mainLoop()将尝试再次安排它。根据{{​​1}}的重新安排策略,下一次计划执行可能是过去的:它将任务的期间添加到任务的上次计划执行时间 。因为在您的情况下,计划的执行时间将在过去超过三秒,因此向它添加三秒仍然会产生下一个计划的执行时间。

那没关系;该算法适应这种滑动。上次运行完成后,您的任务将立即再次运行。你不会得到你想要的每三秒一次行为。相反,你会得到尽可能经常 - 但不要频率超过每三秒

答案 1 :(得分:3)

代码不会同时运行。读这个: http://java.sun.com/javase/6/docs/api/java/util/Timer.html

在scheduleAtFixedRate:

  

在固定速率执行中,每次执行都是相对于初始执行的预定执行时间进行调度的。如果由于任何原因(例如垃圾收集或其他后台活动)延迟执行,则会快速连续执行两次或更多次执行以“赶上”。从长远来看,执行频率将恰好是指定周期的倒数(假设Object.wait(long)下的系统时钟是准确的)。

答案 2 :(得分:1)

查看代码,只有一个线程,因此如果任务的第一次运行时间超过3秒,它将在完成后立即重新启动。另请注意documentation

在固定速率执行中,每次执行都是相对于初始执行的预定执行时间进行调度的。如果执行因任何原因(例如垃圾收集或其他后台活动)而延迟,则会快速连续执行两次或更多次执行以“赶上”。

如果您需要它来启动另一个线程,您应该查看ScheduledThreadPoolExecutor