【发布时间】:2009-12-19 17:12:56
【问题描述】:
我有这个问题:
我有一个计时器。使用 scheduleAtFixedRate 它创建一个新的 Timer 任务。在那个计时器任务中有一些代码,可能需要一段时间才能完成。如何确保 Timer 在前一个任务尚未完成时不会创建新任务?
谢谢
【问题讨论】:
标签: java timer concurrency executorservice executor
我有这个问题:
我有一个计时器。使用 scheduleAtFixedRate 它创建一个新的 Timer 任务。在那个计时器任务中有一些代码,可能需要一段时间才能完成。如何确保 Timer 在前一个任务尚未完成时不会创建新任务?
谢谢
【问题讨论】:
标签: java timer concurrency executorservice executor
我的回答是不要使用Timer,它已经过时了。从 Java5 开始,Timer 已被 ScheduledExecutorService 取代,后者更加灵活且易于使用。您可以更好地控制调度程序的工作方式,这是 Timer 无法获得的那种控制。
您使用Executors 工厂类创建了一个,它有许多工厂方法。您应该查看的是newSingleThreadScheduledExecutor,它应该完全符合您的要求:
创建一个单线程执行器 可以安排命令运行 在给定的延迟之后,或执行 定期。任务保证 顺序执行,不超过 一项任务将在任何给定时间处于活动状态 时间。
使用ScheduledExecutorService,而不是继承TimerTask,而是直接继承Runnable,然后将任务提交给执行者。 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。
【讨论】:
Timer/TimerTask 没有提供任何超越执行器框架的功能。
Timer class 的文档
对应每个Timer对象是 一个后台线程 用于执行所有定时器的 任务,顺序。定时器任务 应该很快完成。如果一个计时器 任务需要过多的时间才能完成, 它“占用”了计时器的任务执行 线。这反过来又会延迟 执行后续任务,其中 可能会“聚集”并快速执行 当(如果)违规时的继承 任务终于完成了。
暗示只有一个后台线程。所以我相信这种情况不会发生。
【讨论】: