【问题标题】:Java: Timer and thread it createsJava:它创建的计时器和线程
【发布时间】:2009-12-19 17:12:56
【问题描述】:

我有这个问题:

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

谢谢

【问题讨论】:

    标签: java timer concurrency executorservice executor


    【解决方案1】:

    我的回答是不要使用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。

    【讨论】:

    • 如果它已经过时并被替换,不应该标记为@deprecated 吗?
    • 在我看来,是的,应该,但 Sun 的弃用规则有点神秘。从功能上讲,Timer/TimerTask 没有提供任何超越执行器框架的功能。
    • 能否请您展示一个使用 newSingleThreadScheduledExecutor 的小例子?我是 java 新手,我从来没有听说过 executors 类。谢谢
    • 嘿,我已经实现了这个,但我遇到了另一个问题 - stackoverflow.com/questions/1937942/…
    【解决方案2】:

    Timer class 的文档

    对应每个Timer对象是 一个后台线程 用于执行所有定时器的 任务,顺序。定时器任务 应该很快完成。如果一个计时器 任务需要过多的时间才能完成, 它“占用”了计时器的任务执行 线。这反过来又会延迟 执行后续任务,其中 可能会“聚集”并快速执行 当(如果)违规时的继承 任务终于完成了。

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

    【讨论】:

    • 不,它仍然会在旧任务尚未完成时创建附加任务,它们只是在第一个任务完成之前不会执行(并且它们可能都在之后立即执行,这不是可能是所需的行为)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 2015-11-13
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    相关资源
    最近更新 更多