【问题标题】:Use executer framework or normal thread?使用执行器框架还是普通线程?
【发布时间】:2013-08-21 09:48:34
【问题描述】:

最近收到一个面试题:

有一种情况,一个线程每隔一小时执行批处理操作,你会使用执行器框架还是普通线程,为什么?

我很困惑。

因为只有一个线程,所以不需要执行器服务。我可以使用whilesleep

while(1)
{
// do task
// t1.sleep(60*60*1000);
}

虽然有一个 ScheduleExecutorService 提供了这么多的调度方法?

最好的方法是什么?

【问题讨论】:

    标签: java multithreading executors scheduledexecutorservice


    【解决方案1】:

    您上面的解决方案的问题是,如果您的任务需要 59 分钟,那么您的线程将花费 59 分钟执行您的任务,然后休眠一个小时。因此,您将每(几乎)2 小时调用一次任务。

    如果您使用预定的执行器框架,那么它会在每小时每小时调用一次您的任务(无论需要多长时间)。另请注意,它可以处理您的任务执行超过一小时的情况(设计或意外)。您可以选择并行启动第二个任务,或跳过后续调用。

    我通常会使用执行器框架。它提供了许多有用的功能,并且您可以封装您的任务,这样它们就不必只是必须在预定的执行程序中运行,而是在任何执行程序中运行。

    【讨论】:

    • 当任务执行超过一小时时,它如何处理场景?它会创建额外的线程吗?
    • 如果您在执行实际工作的 while 块中生成一个新线程,这将无效。
    • 如果您在练习书中有 java 并发,请查看 6.2.5.Delayed and Periodic Tasks 部分。
    • @Raj 我会将其视为设计问题,因为这不太可能是一个好主意。
    • @Raj 这取决于您的实现。如果你只有一个线程,它不会。如果您在此期间产生了一个额外的线程,您将拥有另一个线程,但无论使用 Thread 或 ExecutorService 都是如此。
    【解决方案2】:

    对于这种情况,普通线程与执行服务是错误的二分法。真正的问题应该是,使用旧的Timer 与新的ScheduledExecutorService。即使在 Java 1.2 上,尝试使用普通 Thread 重新实现任务调度也是完全多余的。

    答案将再次是“使用执行器服务”。它更方便、更灵活和可扩展。随着应用程序的增长,使其适应越来越严格的要求几乎是微不足道的。

    计时器 == 旧计时器

    真的,在今天的 Java 中,线程与计时器与 ExecutorService 的整个问题都应该被删除,因为它已被弃用。使用 ExecutorService 不会出错;使用任何其他选项,你就会把自己画到一个角落里。

    【讨论】:

    • 这里为什么不应该使用timer
    • 转过你的问题:为什么ExecutorService不能用于单线程应用程序?我想不出任何好的理由。
    • 因为对于一个非常小的单线程应用程序,使用 ExecutorService 可能是开销?
    • 请注意,ExecutorService 是标准配置。因此没有真正的开销(除了输入额外的几个字符:-))
    • 我支持布赖恩的说法。绝对没有开销;然而,,一个更现代的实现,更快解决任何问题的更好机会,灵活性,可定制性,可扩展性......你说的。
    【解决方案3】:

    我认为这取决于你需要什么。

    ScheduleExecutorService 有一些有用的功能如

    scheduleAtFixedRate:无论您的任务运行多长时间,此调用都将确保您的任务以固定速率运行。比如心跳

    scheduleWithFixedDelay:这个会在你的任务完成后增加一个延迟,例如,一些干净的工作。

    【讨论】:

      【解决方案4】:

      ScheduledExecutorService 应该是一个不错的选择,因为您无需编写代码来定期安排任务。使用经过良好测试的框架比编写自己的框架要好。您可以依赖 ScheduledExecutorService 定期执行配置的任务。这将节省您编写类似功能的时间和精力。

      使用 ScheduledExecutorService 的其他好处是您可以取消任务,可以在任务完成后获取任务状态等。

      【讨论】:

        【解决方案5】:

        ScheduleExecutorService 为您提供了一种通过返回 ScheduledFuture 来检查/取消执行的方法。如果使用单线程,则必须自己实现。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-12
          • 1970-01-01
          • 2012-10-02
          • 1970-01-01
          • 2010-10-04
          相关资源
          最近更新 更多