Java 定时器 vs ExecutorService?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/409932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Timer vs ExecutorService?
提问by kal
I have code where I schedule a task using java.util.Timer
. I was looking around and saw ExecutorService
can do the same. So this question here, have you used Timer
and ExecutorService
to schedule tasks, what is the benefit of one using over another?
我有使用java.util.Timer
. 我环顾四周,看到ExecutorService
可以做同样的事情。所以这个问题,你有没有使用过Timer
并ExecutorService
安排任务,一个使用另一个的好处是什么?
Also wanted to check if anyone had used the Timer
class and ran into any issues which the ExecutorService
solved for them.
还想检查是否有人使用过该Timer
课程并遇到了ExecutorService
为他们解决的任何问题。
采纳答案by Peter ?tibrany
According to Java Concurrency in Practice:
根据实践中的Java并发:
Timer
can be sensitive to changes in the system clock,ScheduledThreadPoolExecutor
isn't.Timer
has only one execution thread, so long-running task can delay other tasks.ScheduledThreadPoolExecutor
can be configured with any number of threads. Furthermore, you have full control over created threads, if you want (by providingThreadFactory
).- Runtime exceptions thrown in
TimerTask
kill that one thread, thus makingTimer
dead :-( ... i.e. scheduled tasks will not run anymore.ScheduledThreadExecutor
not only catches runtime exceptions, but it lets you handle them if you want (by overridingafterExecute
method fromThreadPoolExecutor
). Task which threw exception will be canceled, but other tasks will continue to run.
Timer
可以对系统时钟的变化敏感,ScheduledThreadPoolExecutor
不是。Timer
只有一个执行线程,所以长时间运行的任务会延迟其他任务。ScheduledThreadPoolExecutor
可以配置任意数量的线程。此外,如果您愿意(通过提供ThreadFactory
),您可以完全控制创建的线程。- 在
TimerTask
杀死那个线程时抛出的运行时异常,从而使Timer
死 :-( ... 即计划任务将不再运行。ScheduledThreadExecutor
不仅捕获运行时异常,而且还允许您根据需要处理它们(通过覆盖afterExecute
方法 fromThreadPoolExecutor
)。抛出异常将被取消,但其他任务将继续运行。
If you can use ScheduledThreadExecutor
instead of Timer
, do so.
如果您可以使用ScheduledThreadExecutor
代替Timer
,请这样做。
One more thing... while ScheduledThreadExecutor
isn't available in Java 1.4 library, there is a Backport of JSR 166 (java.util.concurrent
) to Java 1.2, 1.3, 1.4, which has the ScheduledThreadExecutor
class.
还有一件事......虽然ScheduledThreadExecutor
在 Java 1.4 库中不可用,但有一个JSR 166 ( java.util.concurrent
) 到 Java 1.2, 1.3, 1.4 的 Backport,它具有ScheduledThreadExecutor
该类。
回答by Dustin
ExecutorService is newer and more general. A timer is just a thread that periodically runs stuff you have scheduled for it.
ExecutorService 更新且更通用。计时器只是一个线程,它定期运行您为其安排的内容。
An ExecutorService may be a thread pool, or even spread out across other systems in a cluster and do things like one-off batch execution, etc...
ExecutorService 可能是一个线程池,甚至分布在集群中的其他系统中,并执行一次性批处理等操作...
Just look at what each offers to decide.
只要看看每个人提供什么来决定。
回答by Alex Miller
Here's some more good practices around Timer use:
以下是有关 Timer 使用的更多好做法:
http://tech.puredanger.com/2008/09/22/timer-rules/
http://tech.puredanger.com/2008/09/22/timer-rules/
In general, I'd use Timer for quick and dirty stuff and Executor for more robust usage.
一般来说,我会使用 Timer 来处理快速和肮脏的东西,而使用 Executor 来实现更强大的使用。
回答by Neil Coffey
If it's available to you, then it's difficult to think of a reason notto use the Java 5 executor framework. Calling:
如果您可以使用它,那么很难想出不使用 Java 5 执行器框架的理由。调用:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
will give you a ScheduledExecutorService
with similar functionality to Timer
(i.e. it will be single-threaded) but whose access may be slightly more scalable (under the hood, it uses concurrent structures rather than complete synchronization as with the Timer
class). Using a ScheduledExecutorService
also gives you advantages such as:
将为您提供ScheduledExecutorService
与类似的功能Timer
(即它将是单线程的),但其访问可能稍微更具可扩展性(在幕后,它使用并发结构而不是像Timer
类那样完全同步)。使用 aScheduledExecutorService
还可以为您带来以下优势:
- You can customize it if need be (see the
newScheduledThreadPoolExecutor()
or theScheduledThreadPoolExecutor
class) - The 'one off' executions can return results
- 如果需要,您可以自定义它(请参阅
newScheduledThreadPoolExecutor()
或ScheduledThreadPoolExecutor
类) - “一次性”执行可以返回结果
About the only reasons for sticking to Timer
I can think of are:
Timer
我能想到的坚持的唯一原因是:
- It is available pre Java 5
- A similar class is provided in J2ME, which could make porting your application easier (but it wouldn't be terribly difficult to add a common layer of abstraction in this case)
- 它在 Java 5 之前可用
- J2ME 中提供了一个类似的类,它可以使您的应用程序更容易移植(但在这种情况下添加一个公共抽象层并不是非常困难)
回答by Siamaster
My reason for sometimes preferring Timer over Executors.newSingleThreadScheduledExecutor() is that I get much cleaner code when I need the timer to execute on daemon threads.
我有时更喜欢 Timer 而不是 Executors.newSingleThreadScheduledExecutor() 的原因是,当我需要计时器在守护线程上执行时,我得到了更清晰的代码。
compare
相比
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);
with
和
private final Timer timer = new Timer(true);
I do this when I don't need the robustness of an executorservice.
当我不需要 executorservice 的健壮性时,我会这样做。
回答by Ravindra babu
From Oracle documentation page on ScheduledThreadPoolExecutor
来自ScheduledThreadPoolExecutor上的 Oracle 文档页面
A ThreadPoolExecutorthat can additionally schedule commands to run after a given delay, or to execute periodically. This class is preferable to Timerwhen multiple worker threads are needed, or when the additional flexibility or capabilities of ThreadPoolExecutor (which this class extends) are required.
一个ThreadPoolExecutor可以额外安排命令在给定延迟后运行,或定期执行。当需要多个工作线程时,或者需要 ThreadPoolExecutor(此类扩展)的额外灵活性或功能时,此类比Timer更可取。
ExecutorService/ThreadPoolExecutor
or ScheduledThreadPoolExecutor
is obvious choice when you have multiple worker threads.
ExecutorService/ThreadPoolExecutor
或者ScheduledThreadPoolExecutor
当您有多个工作线程时是显而易见的选择。
Pros of ExecutorService
over Timer
的优点ExecutorService
在Timer
Timer
can't take advantage of available CPU cores unlikeExecutorService
especially with multiple tasks using flavours ofExecutorService
like ForkJoinPoolExecutorService
provides collaborative API if you need coordination between multiple tasks. Assume that you have to submit N number of worker tasks and wait for completion of all of them. You can easily achieve it with invokeAllAPI. If you want to achieve the same with multipleTimer
tasks, it would be not simple.ThreadPoolExecutorprovides better API for management of Thread life cycle.
Thread pools address two different problems: they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks
Few advantages:
a. You can create/manage/control life cycle of Threads & optimize thread creation cost overheads
b. You can control processing of tasks ( Work Stealing, ForkJoinPool, invokeAll) etc.
c. You can monitor the progress and health of threads
d. Provides better exception handling mechanism
Timer
无法利用可用的 CPU 内核,ExecutorService
尤其是在使用ForkJoinPoolExecutorService
等风格的多个任务时ExecutorService
如果您需要在多个任务之间进行协调,则提供协作 API。假设您必须提交 N 个工作任务并等待所有任务完成。您可以使用invokeAllAPI轻松实现它。如果要在多个Timer
任务中实现相同的目标,那将不简单。ThreadPoolExecutor为管理线程生命周期提供了更好的 API。
线程池解决两个不同的问题:由于减少了每个任务的调用开销,它们通常在执行大量异步任务时提供改进的性能,并且它们提供了一种限制和管理资源的方法,包括在执行集合时消耗的线程任务。每个 ThreadPoolExecutor 还维护一些基本的统计信息,比如完成的任务数
几个优点:
一种。您可以创建/管理/控制线程的生命周期并优化线程创建成本开销
湾 您可以控制任务的处理(工作窃取、ForkJoinPool、invokeAll)等。
C。您可以监控线程的进度和健康状况
d. 提供更好的异常处理机制