技术栈

2019-03-25——Java并发 Executor框架 Sc

2019-03-25  本文已影响0人  烟雨乱平生

一个特殊的 ExecutorService,提供了 可安排在给定的延迟后运行或定期执行的命令。ScheduledExecutorService,是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
需要注意,只有当调度任务来的时候,ScheduledExecutorService才会真正启动一个线程,其余时间ScheduledExecutorService都是出于轮询任务的状态。

常用方法

方法 说明
schedule(Callable<V> callable,long delay, TimeUnit unit) 延迟指定的时间后执行指定的任务
schedule(Runnable command,long delay, TimeUnit unit) 延迟指定的时间后执行指定的任务
scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit) 是基于固定时间间隔进行任务调度
scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit) 基于不固定时间间隔进行任务调度

ScheduledExecutorService 中两种最常用的调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay。ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔,即每次执行时间为 :initialDelay, initialDelay+period, initialDelay+2period, …;ScheduleWithFixedDelay 每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2executeTime+2*delay。

Timer与ScheduledExecutorService间的区别

java.util.Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。但是,Timer存在一些缺陷,因此你应该考虑使用ScheduledThreadPoolExecutor作为代替品,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。
Timer的另一个问题在于,如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。

上一篇下一篇

猜你喜欢

热点阅读