我有代码,我使用它来安排任务 java.util.timer. 。我环顾四周,看到 ExecutorService 可以做同样的事情。那么这个问题,你使用过Timer和 ExecutorService 要安排任务,使用一种方法比另一种方法有什么好处?

还想检查是否有人使用过 Timer 课堂上遇到的任何问题 ExecutorService 为他们解决了。

有帮助吗?

解决方案

根据 Java 并发实践:

  • Timer 可以对系统时钟的变化敏感, ScheduledThreadPoolExecutor 不是。
  • Timer 只有一个执行线程,因此长时间运行的任务可能会延迟其他任务。 ScheduledThreadPoolExecutor 可以配置任意数量的线程。此外,如果您愿意,您可以完全控制创建的线程(通过提供 ThreadFactory).
  • 运行时抛出异常 TimerTask 杀死那个线程,从而使 Timer 死的 :-( ...IE。计划任务将不再运行。 ScheduledThreadExecutor 不仅捕获运行时异常,而且还可以让您根据需要处理它们(通过覆盖 afterExecute 方法来自 ThreadPoolExecutor)。抛出异常的任务将被取消,但其他任务将继续运行。

如果你可以使用 ScheduledThreadExecutor 代替 Timer, , 这样做。

还有一件事...尽管 ScheduledThreadExecutor 在 Java 1.4 库中不可用,有一个 JSR 166 的向后移植(java.util.concurrent) 到 Java 1.2、1.3、1.4, ,其中有 ScheduledThreadExecutor 班级。

其他提示

如果它对你来说是可用的,那么很难想出理由 不是 使用 Java 5 执行器框架。呼叫:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

会给你一个 ScheduledExecutorService 具有类似的功能 Timer (IE。它将是单线程的),但其访问可能稍微更具可扩展性(在幕后,它使用并发结构而不是像 Timer 班级)。用一个 ScheduledExecutorService 还为您带来以下优势:

  • 如果需要,您可以自定义它(请参阅 newScheduledThreadPoolExecutor() 或者 ScheduledThreadPoolExecutor 班级)
  • “一次性”执行可以返回结果

关于坚持的唯一理由 Timer 我能想到的有:

  • Java 5 之前可用
  • J2ME 中提供了类似的类,这可以使应用程序的移植变得更容易(但在这种情况下添加公共抽象层并不是非常困难)

ExecutorService更新,更通用。计时器只是一个定期运行您为其安排的东西的线程。

ExecutorService可以是一个线程池,甚至可以分布在集群中的其他系统上,并执行一次性批处理执行等操作......

看看每个提供的决定。

以下是关于Timer使用的一些更好的做法:

http://tech.puredanger.com/2008/09/22 /定时器的规则/

一般来说,我会使用Timer来快速和脏的东西和Executor使用更强大。

我有时更喜欢Timer over Executors.newSingleThreadScheduledExecutor()的原因是当我需要在守护程序线程上执行计时器时,我会得到更清晰的代码。

比较

private final ThreadFactory threadFactory = new ThreadFactory() {
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
};
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory); 

private final Timer timer = new Timer(true);

当我不需要执行器服务的健壮性时,我这样做。

来自 ScheduledThreadPoolExecutor <上的Oracle文档页面/ A>

  

ThreadPoolExecutor ,可以额外安排命令在给定延迟后运行,或定期执行。当需要多个工作线程时,或者当需要ThreadPoolExecutor(此类扩展)的额外灵活性或功能时,此类优于 Timer

当您有多个工作线程时,

ExecutorService / ThreadPoolExecutor ScheduledThreadPoolExecutor 是显而易见的选择。

ExecutorService 优先于 Timer

  1. 计时器不能利用可用的CPU核心,这与 ExecutorService 不同,特别是使用 ExecutorService 等多个任务,如 ForkJoinPool
  2. 如果您需要在多个任务之间进行协调,
  3. ExecutorService 会提供协作API。假设您必须提交N个工作任务并等待所有这些任务完成。您可以使用 invokeAll API。如果你想用多个 Timer 任务实现同样的目标,那就不简单了。
  4. ThreadPoolExecutor 提供更好的API来管理线程生命周期。

      

    线程池解决了两个不同的问题:由于减少了每个任务的调用开销,它们通常在执行大量异步任务时提供更高的性能,并且它们提供了一种绑定和管理资源(包括执行时消耗的线程)的方法一系列任务。每个ThreadPoolExecutor还维护一些基本统计信息,例如已完成任务的数量

    几个优点:

    一个。您可以创建/管理/控制线程和生命周期。优化线程创建成本开销

    湾您可以控制任务的处理(工作窃取,ForkJoinPool,invokeAll)等。

    ℃。您可以监视线程的进度和健康状况

    d。提供更好的异常处理机制

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top