并发编程之定时任务&定时线程池原理解析( 二 )

当然我们也可以使用工具类Executors的newScheduledThreadPool的方法 , 快速创建 。注意这里使用的DelayedWorkQueue 。
ScheduledThreadPoolExecutor没有提供带有最大线程数的构造函数的 , 默认是Integer.MAX_VALUE , 说明其可以无限制的开启任意线程执行任务 , 在大量任务系统 , 应注意这一点 , 避免内存溢出 。
核心方法核心方法主要介绍ScheduledThreadPoolExecutor的调度方法 , 其他方法与 ThreadPoolExecutor 一致 。调度方法均由 ScheduledExecutorService 接口定义:
public interface ScheduledExecutorService extends ExecutorService {    // 特定时间延时后执行一次Runnable    public ScheduledFuture<?> schedule(Runnable command,                                       long delay, TimeUnit unit);    // 特定时间延时后执行一次Callable    public <V> ScheduledFuture<V> schedule(Callable<V> callable,                                           long delay, TimeUnit unit);    // 固定周期执行任务(与任务执行时间无关 , 周期是固定的)    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,                                                  long initialDelay,                                                  long period,                                                  TimeUnit unit);     // 固定延时执行任务(与任务执行时间有关 , 延时从上一次任务完成后开始)    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,                                                     long initialDelay,                                                     long delay,                                                     TimeUnit unit);}我们再来看一下接口的实现 , 具体是怎么来实现线程池任务的提交 。因为最终都回调用 delayedExecute 提交任务 。所以 , 我们这里只分析schedule方法 , 该方法是指任务在指定延迟时间到达后触发 , 只会执行一次 。源代码如下:
public ScheduledFuture<?> schedule(Runnable command,                                   long delay,                                   TimeUnit unit) {    //参数校验    if (command == null || unit == null)        throw new NullPointerException();    //这里是一个嵌套结构 , 首先把用户提交的任务包装成ScheduledFutureTask    //然后在调用decorateTask进行包装 , 该方法是留给用户去扩展的 , 默认是个空方法    RunnableScheduledFuture<?> t = decorateTask(command,        new ScheduledFutureTask<Void>(command, null,                                      triggerTime(delay, unit)));   //包装好任务以后 , 就进行提交了 delayedExecute(t);    return t;}


推荐阅读