風吹落叶
2012-12-04 14:12
浏览 615
已采纳

定时器任务 timer.schedule为什么每次任务都晚几秒执行,还有到第二天0点的时候都晚50多分钟?

[color=red]//创建一个定时器,在下一小时的第30分种第一次执行,然后每小时执行一次。[/color]
private void startCollegeIPDay(){
Timer timer = new Timer(true);
long day = 24 * 60 * 60 * 1000;
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 55);
calendar.set(Calendar.SECOND, 0);
timer.schedule(new CollegeDayIPTask(), calendar.getTime(), day);
}

[color=red]//任务task[/color]
public class CollegeIPTask extends TimerTask {
public CollegeIPTask() {
}

    @Override
    public void run() {
        try{
             //业务逻辑
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

}
[color=red]第一次任务没问题,但是从第二次开始没次任务都晚几秒执行,还有到第二天0点的时候直接0点50多分钟才执行,1点的时候直接就2点多才执行,怎么回事?[/color]

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • iteye_7115 2012-12-04 14:43
    已采纳

    这是因为Timer基本处理模型是单线程调度的任务队列模型,Timer不停地接受调度任务,所有任务接受Timer调度后加入TaskQueue,TimerThread不停地去TaskQueue中取任务来执行.此种方式的不足之处为当某个任务执行时间较长,以致于超过了TaskQueue中下一个任务开始执行的时间,会影响整个任务执行的实时性。

    你可以试用scheduleAtFixedRate方法,它会让任务尽量保证在规定的时间频率执行,如:定的时间频率是2s,因为系统繁忙,之后的2.5秒后任务才得以执行第二次,然后,Timer记下了这个延迟,并尝试在下一个任务的时候弥补这个延迟,那么,1.5秒后,任务将执行.

    已采纳该答案
    打赏 评论
  • redstarofsleep 2012-12-04 14:21

    [quote]
    Timer timer = new Timer(true);
    long day = 24 * 60 * 60 * 1000;
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE, 1);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 55);
    calendar.set(Calendar.SECOND, 0);
    timer.schedule(new CollegeDayIPTask(), calendar.getTime(), day);
    [/quote]
    我看这个代码的意思是:从第二天开始,每天的0:55执行一次,

    打赏 评论
  • qq_1017875360_qq 2012-12-04 14:23

    堵塞了。是不是用了多进程之类的啊,可能会存在堵塞。还有一种可能是上次的任务还没有执行完,然后这次任务也启动了,也会存在这种问题的。建议优化一下代码,然后定时尽量把时间隔开点,保证任务很在某个时间范围内执行完。最后还有一个可能,检查服务器的时间,是不是服务器时间和你本机对不上。

    打赏 评论
  • jinnianshilongnian 2012-12-04 17:02

    1、Timer
    [quote]与每个 Timer 对象相对应的是单个后台线程,用于[color=red]顺序地执行所有计时器任务[/color]。计时器任务应该迅速完成。[color=red]如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程[/color]。因此,这就可能延迟后续任务的执行,而这些任务就可能“堆在一起”,并且在上述不友好的任务最终完成时才能够被快速连续地执行。[/quote]
    所以如果任务多可能造成延迟

    2、此类不 提供实时保证 所以晚几秒很正常

    3、
    public void schedule(TimerTask task,
    long delay,
    long period)

    [quote]安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。
    在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。[color=red]如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。[/color][color=red]从长期来看,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。 [/color]

    固定延迟执行适用于那些需要“平稳”运行的重复活动。换句话说,[color=red]它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。[/color]这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人类活动所执行的固定活动,如在按住键时自动重复输入字符。
    [/quote]

    所以不适合你的任务。 可以考虑 quartz。

    打赏 评论
  • M44346460 2012-12-04 20:43

    对于简单的而且实时性不高的任务,可以采用Timer来完成。但是该类在API中也说明了,不能保证触发的时间是正确的。
    目前企业开发方面,大多采用quartz。该框架可以满足你的各种需求,而且使用配置也不难。建议采用该方式!

    打赏 评论

相关推荐 更多相似问题