它是一种可以安排在给定的延迟之后执行一次或周期性执行任务的ThreadPoolExecutor。因为它继承了ThreadPoolExecutor, 当然也具有处理普通Runnable、Callable 任务的能力,当需要多个工作线程辅助时,或者当需要 ThreadPoolExecutor 具有额外的灵活性或功能(该类扩展的这些功能)时,这个类通常比Timer更好。
延迟或周期任务一旦延迟/周期时间到达变得可执行时,它们具体在何时会被线程池调度执行是无法实时保障的,因为同一时期可能有多个任务都需要被执行,该类会按照先进先出FIFO的原则调度执行那些被安排在同一执行时间的任务。
当提交的任务在执行之前被取消,则不会再被执行,但是默认情况下,被取消的任务不会自动从工作队列中被删除,直到它的延迟或者周期时间到达被线程池调度的时候才会从任务队列中被取出,发现已经取消则放弃执行并且不安排周期任务下一次执行,为了避免这种情况,可以调用setRemoveOnCancelPolicy(true)来启用被取消的任务立即从工作队列中删除的特性,默认不开启此特性。
通过scheduleAtFixedRate或scheduleWithFixedDelay提交的周期任务的连续执行不会重叠(即由于某次执行时间较长,前后两次执行不会同时进行)。虽然每一次的执行都是由不同的线程来执行,但是前一次执行的效果会 happen-before 后续执行的效果。周期任务一旦某一次执行任务抛出异常将取消后续的周期执行。
虽然此类继承了ThreadPoolExecutor,但使用了一个*的任务队列(延迟工作队列DelayedWorkQueue),因此对maximumPoolSize的调整将对此类没有任何作用。此外,将corePoolSize设置为零或使用allowCoreThreadTimeOut几乎从来都不是一个好主意,因为这可能会使线程池在需要运行任务时没有线程来处理这些任务。
扩展注意事项,该类重写了execute和submit方法来生成内部ScheduledFuture对象,以控制每个任务的延迟和调度。为了保持功能,子类中对这些方法的任何进一步重写都必须依赖父类的版本,这将有效地避免自定义额外的任务类型。但是该类提供了另一种可被重写的方法decorateTask (Runnable和Callable各有一个版本),可定制用于通过execute、submit、schedule、scheduleAtFixedRate和scheduleWithFixedDelay方法传入的任务的具体类型,默认情况下,ScheduledThreadPoolExecutor使用一个扩展了FutureTask、RunnableScheduledFuture的任务类型ScheduledFutureTask。但是,可以使用下列形式的子类修改或替换该类型:
1 public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor { 2 3 //自定义RunnableScheduledFuture 4 static class CustomTask<V> implements RunnableScheduledFuture<V> { ... } 5 6 //重写decorateTask,返回自定义的RunnableScheduledFuture 7 protected <V> RunnableScheduledFuture<V> decorateTask( 8 Runnable r, RunnableScheduledFuture<V> task) { 9 return new CustomTask<V>(r, task); 10 } 11 12 protected <V> RunnableScheduledFuture<V> decorateTask( 13 Callable<V> c, RunnableScheduledFuture<V> task) { 14 return new CustomTask<V>(c, task); 15 } 16 // ... add constructors, etc. 17 }