Java定时器与执行器服务?

Java定时器与执行器服务?,java,timer,scheduled-tasks,scheduling,executorservice,Java,Timer,Scheduled Tasks,Scheduling,Executorservice,我使用java.util.Timer计划任务的代码。我环顾四周,发现执行器服务也能做同样的事情。因此,这里的问题是,您是否使用了定时器和执行器服务来安排任务,一个使用比另一个使用有什么好处 还想检查是否有人使用了定时器类并遇到了ExecutorService为他们解决的任何问题。ExecutorService更新且更通用。计时器只是一个线程,它定期运行您为它安排的内容 ExecutorService可以是一个线程池,甚至可以分布在集群中的其他系统中,执行一次性批处理执行等操作 只需看看每种产品都

我使用
java.util.Timer
计划任务的代码。我环顾四周,发现执行器服务也能做同样的事情。因此,这里的问题是,您是否使用了
定时器
执行器服务
来安排任务,一个使用比另一个使用有什么好处


还想检查是否有人使用了
定时器
类并遇到了
ExecutorService
为他们解决的任何问题。

ExecutorService更新且更通用。计时器只是一个线程,它定期运行您为它安排的内容

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

只需看看每种产品都提供了什么就可以做出决定。

根据:

  • 计时器
    可能对系统时钟的变化敏感,
    ScheduledThreadPoolExecutor
    则不敏感
  • Timer
    只有一个执行线程,因此长时间运行的任务可能会延迟其他任务<代码>ScheduledThreadPoolExecutor可以配置任意数量的线程。此外,如果需要,您可以完全控制创建的线程(通过提供
    ThreadFactory
  • TimerTask
    中抛出的运行时异常会杀死这一个线程,从而使
    Timer
    死机:-(…即计划任务将不再运行。
    ScheduledThreadExecutor
    不仅捕获运行时异常,还允许您在需要时处理它们(通过重写
    ThreadPoolExecutor
    中的
    afterExecute
    方法)。引发异常的任务将被取消,但其他任务将继续运行
如果可以使用
ScheduledThreadExecutor
而不是
Timer
,请这样做


还有一件事……虽然Java 1.4库中没有
ScheduledThreadExecutor
,但是有一个类,它有
ScheduledThreadExecutor
类。

这里有一些关于计时器使用的好做法:


一般来说,我会使用Timer来处理快速和不干净的东西,而Executor则用于更健壮的使用。

如果您可以使用它,那么很难找到不使用Java 5 Executor框架的理由。调用:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
将为您提供一个
ScheduledExecutorService
,其功能类似于
Timer
(即,它将是单线程的),但其访问可能更具可扩展性(在后台,它使用并发结构,而不是与
Timer
类完全同步)。使用
ScheduledExecutorService
还可以为您提供以下优势:

  • 您可以根据需要对其进行自定义(请参阅
    newScheduledThreadPoolExecutor()
    ScheduledThreadPoolExecutor
    类)
  • “一次性”执行可以返回结果
关于坚持使用
定时器的唯一原因,我能想到的是:

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

我有时更喜欢定时器而不是执行器。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); 


当我不需要executorservice的健壮性时,我会这样做。

来自上的Oracle文档页

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

当您有多个工作线程时,
ExecutorService/ThreadPoolExecutor
ScheduledThreadPoolExecutor
是明显的选择

ExecutorService
over
Timer

  • Timer
    无法利用可用的CPU内核,这与
    ExecutorService
    不同,尤其是对于使用
    ExecutorService
    等样式的多个任务
  • ExecutorService
    如果您需要在多个任务之间进行协调,则提供协作API。假设您必须提交N个辅助任务并等待所有任务完成。您可以使用API轻松实现。如果您希望在多个
    计时器
    任务中实现相同的任务,这将不简单
  • 为线程生命周期的管理提供更好的API

    线程池解决了两个不同的问题:它们通常在执行大量异步任务时提供改进的性能,这是因为减少了每个任务的调用开销;它们提供了一种方法来限制和管理执行任务集合时消耗的资源,包括线程。每个线程池执行器还包含一些基本统计信息,例如已完成任务的数量

    几个优点:

    a、 您可以创建/管理/控制线程的生命周期,并优化线程创建成本开销

    b、 您可以控制任务的处理(工作窃取、ForkJoinPool、invokeAll)等

    c、 您可以监视线程的进度和运行状况

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


  • 我确实有一个计时器的问题,我用ScheduledExecutorService来修复它


    问题是计时器取决于系统时间,每次我更改它时,它都会影响应用程序的功能。因此,我将计时器替换为ScheduledExecutorService,现在它工作正常。

    如果您需要更具功能的功能,请查看。它为您提供了更多的作业控制,包括类似于cron的调度、clu和ster感知调度,作业的个性化控制(conce
    private final Timer timer = new Timer(true);