当前位置:  开发笔记 > 编程语言 > 正文

Java Timer vs ExecutorService?

如何解决《JavaTimervsExecutorService?》经验,为你挑选了6个好方法。

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

还想检查是否有人使用过该ExecutorService课程并遇到了Timer为他们解决的任何问题.



1> Peter Štibra..:

根据Java Concurrency in Practice:

Timer可能对系统时钟的变化很敏感,ScheduledThreadPoolExecutor不是.

Timer只有一个执行线程,因此长时间运行的任务可以延迟其他任务.ScheduledThreadPoolExecutor可以配置任意数量的线程.此外,如果需要(通过提供ThreadFactory),您可以完全控制创建的线程.

抛出运行时异常会TimerTask杀死一个线程,从而导致Timer死:( ...即计划任务将不再运行.ScheduledThreadExecutor不仅捕获运行时异常,而且它允许您根据需要处理它们(通过重写afterExecute方法ThreadPoolExecutor).抛出异常将被取消,但其他任务将继续运行.

如果您可以使用ScheduledThreadExecutor而不是Timer,请执行此操作.

还有一件事......虽然ScheduledThreadExecutor在Java 1.4库中不可用,但有一个JSR 166(java.util.concurrent)的Backport 到Java 1.2,1.3,1.4,它有ScheduledThreadExecutor类.



2> Neil Coffey..:

如果您可以使用它,那么很难想到使用Java 5执行程序框架的原因.呼叫:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

将给你一个ScheduledExecutorService具有类似功能Timer(即它将是单线程),但其访问可能稍微更具可扩展性(在引擎盖下,它使用并发结构而不是与Timer类完全同步).使用a ScheduledExecutorService还具有以下优点:

如果需要,您可以自定义它(参见newScheduledThreadPoolExecutor()ScheduledThreadPoolExecutor类)

"一次性"执行可以返回结果

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

它在Java 5之前可用

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


另一个注意事项:我在2k17写这篇评论,没有更多的J2ME.它已经死了.

3> Dustin..:

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

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

只需看看每个提供的决定.



4> Alex Miller..:

这里有一些关于Timer使用的更好的做法:

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

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



5> Ravindra bab..:

从ScheduledThreadPoolExecutor上的Oracle文档页面

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

ExecutorService/ThreadPoolExecutor或者ScheduledThreadPoolExecutor当您有多个工作线程时,这是显而易见的选择。

ExecutorService超过的优点Timer

    Timer不能利用可用的CPU内核, ExecutorService尤其是在使用ExecutorService诸如ForkJoinPool之类的多种任务的情况下

    ExecutorService如果需要在多个任务之间进行协调,则提供协作式API。假设您必须提交N个工作者任务,然后等待所有任务完成。您可以使用invokeAll API 轻松实现它。如果您想通过多个Timer任务来实现相同的目标,那将不容易。

    ThreadPoolExecutor提供了更好的API,用于管理线程生命周期。

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

    几个优点:

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

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

    C。您可以监视线程的进度和运行状况

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



6> Siamaster..:

我有时更喜欢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);

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

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有