7

我有这个问题:

我有一个计时器。使用 scheduleAtFixedRate 它创建一个新的 Timer 任务。在那个计时器任务中有一些代码,可能需要一段时间才能完成。当前一个任务尚未完成时,如何确保 Timer 不会创建新任务?

谢谢

4

2 回答 2

18

我的回答是不要使用Timer,它已经过时了。自 Java5 以来,Timer已被 . 取代ScheduledExecutorService,后者更加灵活且易于使用。您可以更好地控制调度程序的工作方式,这是您无法获得的那种控制Timer

您可以使用Executors工厂类创建一个,它有许多工厂方法。您应该查看的是newSingleThreadScheduledExecutor,它应该完全符合您的要求:

创建一个单线程执行程序,可以安排命令在给定延迟后运行,或定期执行。任务保证按顺序执行,并且在任何给定时间不会有超过一个任务处于活动状态。

使用 a ScheduledExecutorService,而不是 subclassing TimerTask,您可以Runnable直接子类化,然后将任务提交给 executor。executor 上有多种方法,您需要选择适合您需求的方法(请ScheduledExecutorService仔细阅读 javadoc),但要点是这样的:

    // initialise the executor
    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    while (tasksRemaining) {
        // create your task
        Runnable task = ....;
        // submit it to the executor, using one of the various scheduleXYZ methods
        executor.schedule(task, delay, unit);
    }

    // when everything is finished, shutdown the executor
    executor.shutdown();

与往常一样,阅读 javadoc。

于 2009-12-19T17:15:54.317 回答
3

Timer 类的文档

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

表明只有一个后台线程。所以我相信这种情况不会发生。

于 2009-12-19T17:15:04.310 回答