Answers:
根据实践中的Java并发性:
Timer
对系统时钟的变化很敏感,ScheduledThreadPoolExecutor
不是。Timer
只有一个执行线程,因此长时间运行的任务可能会延迟其他任务。ScheduledThreadPoolExecutor
可以配置任意数量的线程。此外,您可以根据需要完全控制创建的线程(通过提供ThreadFactory
)。TimerTask
杀死一个线程,从而导致Timer
死机:-( ...即已调度的任务将不再运行。ScheduledThreadExecutor
不仅捕获运行时异常,而且还允许您根据需要处理它们(通过覆盖afterExecute
方法ThreadPoolExecutor
)。抛出异常将被取消,但其他任务将继续运行。如果可以ScheduledThreadExecutor
代替使用Timer
,请这样做。
还有一件事...尽管ScheduledThreadExecutor
Java 1.4库中没有该功能,但是有一个将JSR 166(java.util.concurrent
)反向移植到Java 1.2、1.3、1.4的ScheduledThreadExecutor
类。
如果您可以使用它,那么很难考虑不使用Java 5执行程序框架的原因。致电:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
会为您提供ScheduledExecutorService
与相似的功能Timer
(即它将是单线程的),但其访问权限可能会稍微扩展(在幕后,它使用并发结构而不是像使用Timer
类那样进行完全同步)。使用a ScheduledExecutorService
还可以为您带来以下优势:
newScheduledThreadPoolExecutor()
或ScheduledThreadPoolExecutor
类)Timer
我能想到的唯一坚持的理由是:
TimerTask
可能是scheduledExecutionTime()
方法的可用性似乎在中没有任何等效方法ScheduledExecutorService
。
以下是有关Timer使用的一些更好的做法:
http://tech.puredanger.com/2008/09/22/timer-rules/
总的来说,我会使用Timer来处理快速而肮脏的东西,而使用Executor来实现更强大的用法。
从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。提供更好的异常处理机制
我之所以有时偏爱计时器而不是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的鲁棒性时,我会这样做。