我有时更喜欢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);
6 回答
根据Java Concurrency in Practice:
Timer
可能对系统时钟的变化很敏感,ScheduledThreadPoolExecutor
不是 .Timer
只有一个执行线程,因此长时间运行的任务可以延迟其他任务 .ScheduledThreadPoolExecutor
可以配置任意数量的线程 . 此外,如果需要,您可以完全控制已创建的线程(通过提供ThreadFactory
) .在
TimerTask
中抛出的运行时异常会杀死一个线程,从而使Timer
死了:-( ...即计划任务将不再运行.ScheduledThreadExecutor
不仅捕获运行时异常,而且可以让你根据需要处理它们(通过覆盖afterExecute
方法)来自ThreadPoolExecutor
) . 抛出异常的任务将被取消,但其他任务将继续运行 .如果您可以使用
ScheduledThreadExecutor
而不是Timer
,请执行此操作 .还有一件事......虽然在Java 1.4库中没有
ScheduledThreadExecutor
,但是有一个Backport of JSR 166 (java.util.concurrent) to Java 1.2, 1.3, 1.4,它有ScheduledThreadExecutor
类 .如果's available to you, then it'很难想到不使用Java 5 Actuator 框架的原因 . 呼叫:
会给你
ScheduledExecutorService
具有与Timer
类似的功能(即它将是单线程的),但其访问可能稍微更具可扩展性(在引擎盖下,它使用并发结构而不是像Timer
类那样完全同步) . 使用ScheduledExecutorService
还可以为您提供以下优势:如果需要,您可以自定义它(参见
newScheduledThreadPoolExecutor()
或ScheduledThreadPoolExecutor
类)'one off'执行可以返回结果
关于坚持
Timer
的唯一原因我能想到的是:它在Java 5之前可用
J2ME中提供了类似的类,它可以使您的应用程序移植更容易(但在这种情况下添加公共抽象层并不是非常困难)
ExecutorService更新,更通用 . 计时器只是一个定期运行您为其安排的东西的线程 .
ExecutorService可以是一个线程池,甚至可以分布在集群中的其他系统上,并执行诸如一次性批处理执行等操作 .
只需看看每个提供的决定 .
这里有一些关于Timer使用的更好的做法:
http://tech.puredanger.com/2008/09/22/timer-rules/
一般来说,我会使用Timer来快速和脏的东西和Executor使用更强大 .
我有时更喜欢Timer over Executors.newSingleThreadScheduledExecutor()的原因是当我需要在守护程序线程上执行计时器时,我得到了更清晰的代码 .
相比
同
当我不需要 Actuator 服务的健壮性时,我这样做 .
来自ScheduledThreadPoolExecutor上的Oracle文档页面
当您有多个工作线程时,
ExecutorService/ThreadPoolExecutor
或ScheduledThreadPoolExecutor
是显而易见的选择 .ExecutorService
的优点Timer
Timer
无法利用可用的CPU核心,而不像ExecutorService
,尤其是使用ExecutorService
的_1192242_类似的多个任务如果您需要在多个任务之间进行协调,
ExecutorService
会提供协作API . 假设您必须提交N个工作任务并等待所有这些任务完成 . 您可以使用invokeAll API轻松实现它 . 如果你想用多个Timer
任务实现相同的目标,那就不简单了 .ThreadPoolExecutor为管理线程生命周期提供了更好的API .
几个优点:
一个 . 您可以创建/管理/控制线程的生命周期并优化线程创建成本开销
湾您可以控制任务的处理(工作窃取,ForkJoinPool,invokeAll)等 .
C . 您可以监视线程的进度和运行状况
d . 提供更好的异常处理机制