Java定时器与ExecutorService?

我有我使用java.util.timer计划任务的代码。 我环顾四周,看到ExecutorService可以做同样的事情。 所以这里的这个问题,你使用Timer和ExecutorService来调度任务,一个使用另一个的好处是什么?

也想检查是否有人使用了Timer类,并遇到ExecutorService为他们解决的任何问题。

根据Java并发实践 :

  • Timer可以对系统时钟的变化敏感, ScheduledThreadPoolExecutor不是。
  • Timer只有一个执行线程,所以长时间运行的任务可以延迟其他任务。 ScheduledThreadPoolExecutor可以configuration任意数量的线程。 此外,你可以完全控制创build的线程,如果你想(通过提供ThreadFactory )。
  • TimerTask抛出的运行时exceptionTimerTask一个线程,从而导致Timer死机:-( …即计划的任务将不再运行afterExecute不仅捕获运行时exception,但它可以让你处理它们,如果你想(通过重写afterExecute方法ThreadPoolExecutor )抛出exception的任务将被取消,但其他任务将继续运行。

如果您可以使用ScheduledThreadExecutor而不是Timer ,那就这样做。

还有一件事情…虽然ScheduledThreadExecutor在Java 1.4库中不可用,但是Java 1.2,1.3,1.4的JSR 166( java.util.concurrent )的Backport具有ScheduledThreadExecutor类。

如果它对您有用,那么很难想到使用Java 5执行器框架的原因。 呼叫:

 ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 

会给你一个与Timer类似的ScheduledExecutorService (即它将是单线程的),但是它的访问可能稍微更具可扩展性(在引擎盖下,它使用并发结构而不像Timer类那样完成同步)。 使用ScheduledExecutorService还可以带来以下优点:

  • 您可以根据需要自定义它(请参阅newScheduledThreadPoolExecutor()ScheduledThreadPoolExecutor类)
  • “一次性”执行可以返回结果

坚持Timer我可以想到的唯一原因是:

  • 它在Java 5之前是可用的
  • 在J2ME中提供了一个类似的类,它可以使你的应用程序更容易移植(但是在这种情况下增加一个通用的抽象层并不是件难事)

ExecutorService更新更通用。 计时器只是一个定期运行你已经安排好的东西的线程。

一个ExecutorService可能是一个线程池,甚至跨群集中的其他系统分布,并执行一次性批处理执行等等。

只要看看每个提供的决定。

以下是围绕Timer使用的一些更好的实践:

http://tech.puredanger.com/2008/09/22/timer-rules/

一般来说,我会使用计时器快速和肮脏的东西和执行器更强大的用法。

我有时宁愿使用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); 

当我不需要executorservice的鲁棒性,我这样做。

从ScheduledThreadPoolExecutor的 oralce文档页面

一个ThreadPoolExecutor ,它可以附加地计划命令在给定延迟之后运行,或者定期执行。 当需要多个工作线程时,或者需要额外的灵活性或ThreadPoolExecutor(该类扩展)的function时,此类比Timer更可取。

有多个工作线程时, ExecutorService/ThreadPoolExecutorScheduledThreadPoolExecutor是显而易见的select。

ExecutorService优于Timer优点

  1. Timer不能像ExecutorService那样利用可用的CPU内核,特别是使用ExecutorService多个任务,比如ForkJoinPool
  2. 如果您需要多任务之间的协调,则ExecutorService提供协作API。 假设你必须提交N个工作任务并等待所有工作完成。 你可以用invokeAll API轻松实现。 如果你想在多个Timer任务中实现同样的function,那将不是那么简单。
  3. ThreadPoolExecutor为线程生命周期的pipe理提供了更好的API。

    线程池解决了两个不同的问题:由于减less了每个任务的调用开销,它们通常在执行大量的asynchronous任务时提供改进的性能,并且提供了一种限制和pipe理资源(包括线程)的方法,在执行任务。 每个ThreadPoolExecutor还维护一些基本的统计信息,例如完成的任务数量

    几个优点:

    一个。 您可以创build/pipe理/控制线程的生命周期并优化线程创build成本的开销

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

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

    d。 提供更好的exception处理机制